【问题标题】:Dataframe: compare column value and one row below数据框:比较列值和下面的一行
【发布时间】:2020-02-22 09:00:19
【问题描述】:

我有一个带有方向的数据框:

        Direction: 
2/01/19 None
1/31/19 Upward
1/30/19 None
1/29/19 None
1/28/19 Downward
1/27/19 None
1/26/19 None
1/25/19 Upward

我想根据以下条件(从 2019 年 1 月 25 日开始)创建一个“动量”列:
1. 如果相应日期的方向为“向上”,则将该值设置为“向上'
2. 如果 Momentum 中下面的第一行是“向上”,则将其设置为“向上”
3. 如果对应日期的Direction为“Downward”,则设置为“None”
4.否则,设置为“无”

换句话说,一旦你达到“向上”状态,它应该保持这种状态,直到你点击“向下”

结果应该是这样的:

        Direction:  Momentum:
2/01/19 None        Upward
1/31/19 Upward      Upward
1/30/19 None        None
1/29/19 None        None
1/28/19 Downward    None
1/27/19 None        Upward
1/26/19 None        Upward
1/25/19 Upward      Upward

有没有办法在不使用循环的情况下做到这一点?

【问题讨论】:

    标签: python pandas dataframe np


    【解决方案1】:

    这是一种方法。喝杯咖啡后我会尝试改进它...

    df['Momentum:'] = None  # Base case.
    df.loc[df['Direction:'].eq('Upward'), 'Momentum:'] = 'Upward'
    df.loc[df['Direction:'].eq('Downward'), 'Momentum:'] = 1  # Temporary value.
    df.loc[:, 'Momentum:'] = df['Momentum:'].bfill()
    df.loc[df['Momentum:'].eq(1), 'Momentum:'] = None  # Set temporary value back to None.
    >>> df
            Direction: Momentum:
    2/01/19       None    Upward
    1/31/19     Upward    Upward
    1/30/19       None      None
    1/29/19       None      None
    1/28/19   Downward      None
    1/27/19       None    Upward
    1/26/19       None    Upward
    1/25/19     Upward    Upward
    

    【讨论】:

    • 感谢您的反馈。但是,如果有两个或多个连续的“无”,这将不起作用。一旦你达到“向上”状态,它应该保持这种状态,直到你点击“向下”
    • 您能否修改您的示例以包含这种情况?
    • 太棒了!非常感谢@Alexander 的编辑回复!
    【解决方案2】:

    用新数据编辑答案首先回填None值,然后将Downward替换为Nones:

    #first replace strings Nones to None type
    df['Direction:'] = df['Direction:'].mask(df['Direction:'] == 'None', None)
    
    df['Momentum:'] = df['Direction:'].bfill().mask(lambda x: x == 'Downward', None)
    

    或者:

    s = df['Direction:'].bfill()
    df['Momentum:'] = s.mask(s == 'Downward', None)
    

    print (df)
            Direction:  Momentum:
    2/01/19       None     Upward
    1/31/19     Upward     Upward
    1/30/19       None       None
    1/29/19       None       None
    1/28/19   Downward       None
    1/27/19       None     Upward
    1/26/19       None     Upward
    1/25/19     Upward     Upward
    

    旧答案:

    numpy.where 与链式布尔掩码一起使用,比较移位值以及| 的原始值进行按位或:

    mask = df['Direction:'].eq('Upward') | df['Direction:'].shift(-1).eq('Upward')
    df['Momentum:'] = np.where(mask, 'Upward', None)
    print (df)
            Direction: Momentum:
    1/31/19       None    Upward
    1/30/19     Upward    Upward
    1/29/19       None      None
    1/28/19       None      None
    1/27/19   Downward      None
    1/26/19       None    Upward
    1/25/19     Upward    Upward
    

    【讨论】:

    • 感谢您的回复。仅供参考:我根据@Alexander 下面的建议编辑了我的原始帖子。
    • @Drive2blue - 是的,我认为这个新数据是在几分钟前编辑的。
    • hmmm...当我尝试使用回填的建议时,我没有得到相同的结果。我的动量列是 Direction 的精确副本,除了 Downward 被 None 替换
    • @Drive2blue - 也许Nones 是字符串,在我的解决方案之前df['Direction:'] = df['Direction:'].mask(df['Direction:'] == 'None', None) 如何工作?
    • 啊!而已。它现在可以工作了 :) 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2017-01-08
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 2018-03-14
    • 2020-08-13
    • 1970-01-01
    相关资源
    最近更新 更多