【问题标题】:Calculate value based on neighbouring rows in Python Pandas根据 Python Pandas 中的相邻行计算值
【发布时间】:2019-07-23 05:09:41
【问题描述】:

我有成对的值(参见“mjd”列),格式为 pandas 数据框:

    cor      est        rms     apr         mjd
0   0.12359  80.53359   0.01639 80.41       57754.0
1   -0.01281 80.21719   0.01642 80.23       57755.0
2   0.03876  80.26876   0.01743 80.23       57755.0
3   0.08924  80.40924   0.01779 80.32       57756.0
4   0.06863  80.38863   0.01686 80.32       57756.0
5   -0.07582 80.01417   0.01748 80.08999    57757.0
6   0.13964  80.22963   0.01773 80.08999    57757.0
7   0.03911  79.01908   0.01809 78.97997    57758.0

现在,我想创建一个具有相同列但计算第 0 行和第 1 行相邻序列的平均值的新数据框; 2和3; 4和5等。

预期输出:

    cor     est     rms     apr     mjd
0   0.05539 80.3754 0.01640 80.32   57754.5 
1   0.064   80.339  0.01761 80.275  57755.5
2   -0.0035 80.2014 0.01717 80.2049 57756.5
3   0.08937 79.6243 0.01791 79.5349 57757.5

【问题讨论】:

  • 数字的预期输出是什么?

标签: python pandas dataframe


【解决方案1】:

您可以使用df.index // 2进行分组:

In [11]: df.index // 2
Out[11]: Int64Index([0, 0, 1, 1, 2, 2, 3, 3], dtype='int64')

In [12]: df.groupby(df.index // 2).mean()
Out[12]:
        cor        est       rms        apr      mjd
0  0.055390  80.375390  0.016405  80.320000  57754.5
1  0.064000  80.339000  0.017610  80.275000  57755.5
2 -0.003595  80.201400  0.017170  80.204995  57756.5
3  0.089375  79.624355  0.017910  79.534980  57757.5

【讨论】:

    【解决方案2】:

    比其他答案提供的 GroupBy 解决方案快大约 20%,您还可以使用 rolling 平均值,然后使用 iloc 选择每隔一个元素:

    df.rolling(2).mean().iloc[1::2]
    #        cor        est       rms        apr      mjd
    #1  0.055390  80.375390  0.016405  80.320000  57754.5
    #3  0.064000  80.339000  0.017610  80.275000  57755.5
    #5 -0.003595  80.201400  0.017170  80.204995  57756.5
    #7  0.089375  79.624355  0.017910  79.534980  57757.5
    
    %timeit df.rolling(2).mean().iloc[1::2]
    #1.17 ms ± 74.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    %timeit df.groupby(df.index // 2).mean()
    #1.47 ms ± 110 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

    请注意,此解决方案确实为您提供了与其他答案不同的索引。 通过一些额外的测试,我发现rolling 解决方案的速度更快到大约 10K 行,之后GroupBy 更快:

    df = pd.DataFrame(np.random.rand(100000, 5))
    %timeit df.rolling(2).mean().iloc[1::2].reset_index(drop=True)
    %timeit df.groupby(df.index // 2).mean()
    #25.5 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    #23.1 ms ± 1.66 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    【讨论】:

    • 小建议,尝试在大数据中测试它(可能是相同的时间,也可能不是)
    • 我添加了更大数据集的测试结果
    • 是的,我同意!对于我大约 1500 行的数据集,滚动方法更快。
    【解决方案3】:

    df.rolling(2).mean()[1::2]

    说明:

    rolling(2) 将为每两个连续的行计算 mean()。结果数据框的第一行将显示Nan,因为没有以前的值来计算平均值。下一行将显示原始数据帧的第一行和第二行的平均值等。现在,如果要将数据帧减少一半,请计算非重叠序列的平均值(行 0 和 1;2 和 3;4 和 5等),然后使用[1::2] 索引器仅选择每隔一行。

    【讨论】:

      猜你喜欢
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-18
      • 1970-01-01
      相关资源
      最近更新 更多