【问题标题】:Comparing single dataframe value to previous 10 in same column将单个数据帧值与同一列中的前 10 个值进行比较
【发布时间】:2016-01-22 05:48:14
【问题描述】:

在数据框中,我想计算前 10 天的价格有多少高于今天的价格。结果如下所示:

price   ct>prev10
50.00   
51.00   
52.00   
50.50   
51.00   
50.00   
50.50   
53.00   
52.00   
49.00   
51.00   3

我看到 DSM 回复了这篇帖子,但要求不同,因为比较的基数是静态数字,而不是当前行:

Achieving "countif" with pd.rolling_sum()

当然,我想在不循环 1x1 的情况下执行此操作。非常难过-提前感谢您的任何建议。

【问题讨论】:

    标签: python pandas conditional dataframe vectorization


    【解决方案1】:

    您可以在系列上使用rolling_apply 函数。考虑到样本数据的大小,我使用了 5 的窗口长度,但您可以轻松更改它。

    lambda函数统计滚动组中的项数(不包括最后一项)大于最后一项。

    df = pd.DataFrame({'price': [50, 51, 52, 50.5, 51, 50, 50.5, 53, 52, 49, 51]})
    
    window = 5  # Given that sample data only contains 11 values.
    df['price_count'] = pd.rolling_apply(df.price, window, 
                                         lambda group: sum(group[:-1] > group[-1]))
    >>> df
        price  price_count
    0    50.0          NaN
    1    51.0          NaN
    2    52.0          NaN
    3    50.5          NaN
    4    51.0            1
    5    50.0            4
    6    50.5            2
    7    53.0            0
    8    52.0            1
    9    49.0            4
    10   51.0            2
    

    在上面的示例中,第一组是索引值为 0-4 的价格。你可以看到发生了什么:

    group = df.price[:window].values
    >>> group
    array([ 50. ,  51. ,  52. ,  50.5,  51. ])
    

    现在,将前四个价格与当前价格进行比较:

    >>> group[:-1] > group[-1]
    array([False, False,  True, False], dtype=bool)
    

    然后,您只是对布尔值求和:

    >>> sum(group[:-1] > group[-1])
    1
    

    这是在索引 4 处放入第一个关闭窗口的值。

    【讨论】:

    • 嗨,Alexander,感谢您的快速响应。我相信这正是我所需要的,但我还没有完全理解它。如果我想让回溯期为 5 天,不包括今天,我将如何调整你写的内容?我知道我可以使 window=6,但为了更好地理解您的解决方案,它会是:pd.rolling_apply(df.price, window, lambda group: sum(group[:-1] > group[-2])) ?
    • 窗口的最后一天被排除在比较之外。请参阅上面的编辑。
    【解决方案2】:

    这是一个带有NumPy 模块的向量化方法,它支持broadcasting 来实现向量化方法 -

    import numpy as np
    import pandas as pd
    
    # Sample input dataframe
    df = pd.DataFrame({'price': [50, 51, 52, 50.5, 51, 50, 50.5, 53, 52, 49, 51]})
    
    # Convert to numpy array for counting purposes
    A = np.array(df['price'])
    
    W = 5 # Window size
    
    # Initialize another column for storing counts
    df['price_count'] = np.nan
    
    # Get counts and store as a new column in dataframe
    C = (A[np.arange(A.size-W+1)[:,None] + np.arange(W-1)] > A[W-1:][:,None]).sum(1)
    df['price_count'][W-1:] = C
    

    示例运行 -

    >>> df
        price
    0    50.0
    1    51.0
    2    52.0
    3    50.5
    4    51.0
    5    50.0
    6    50.5
    7    53.0
    8    52.0
    9    49.0
    10   51.0
    >>> A = np.array(df['price'])
    >>> W = 5 # Window size
    >>> df['price_count'] = np.nan
    >>> 
    >>> C=(A[np.arange(A.size-W+1)[:,None] + np.arange(W-1)] > A[W-1:][:,None]).sum(1)
    >>> df['price_count'][W-1:] = C
    >>> df
        price  price_count
    0    50.0          NaN
    1    51.0          NaN
    2    52.0          NaN
    3    50.5          NaN
    4    51.0            1
    5    50.0            4
    6    50.5            2
    7    53.0            0
    8    52.0            1
    9    49.0            4
    10   51.0            2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-26
      • 2021-10-27
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      • 1970-01-01
      • 2018-05-16
      • 1970-01-01
      相关资源
      最近更新 更多