NumPythonic方法是将元素提取为一个带有df.values的NumPy数组,然后沿axis=1和4的2元素重塑为axis=1和4数组,并沿axis=2执行平均缩减,最后转换回数据帧,如下所示-pd.DataFrame(df.values.reshape(-1,2,df.shape[1]).mean(1))
事实证明,您可以引入NumPy非常有效的工具:^{}来完成这项工作average-reduction作为sum-reduction和scaling-down的组合,就像这样-pd.DataFrame(np.einsum('ijk->ik',df.values.reshape(-1,2,df.shape[1]))/2.0)
请注意,建议的方法假设行数可以被2整除。
同样作为^{},要保留列名,在转换回Dataframe时需要添加columns=df.columns,即-pd.DataFrame(...,columns=df.columns)
样本运行->>> df
0 1 2 3
0 2 50 25 26
1 4 11 38 44
2 6 33 16 25
3 8 37 27 25
4 10 28 48 32
5 12 47 35 45
6 14 8 16 7
7 16 12 16 30
8 18 22 39 29
9 20 9 15 47
>>> pd.DataFrame(df.values.reshape(-1,2,df.shape[1]).mean(1))
0 1 2 3
0 3 30.5 31.5 35.0
1 7 35.0 21.5 25.0
2 11 37.5 41.5 38.5
3 15 10.0 16.0 18.5
4 19 15.5 27.0 38.0
>>> pd.DataFrame(np.einsum('ijk->ik',df.values.reshape(-1,2,df.shape[1]))/2.0)
0 1 2 3
0 3 30.5 31.5 35.0
1 7 35.0 21.5 25.0
2 11 37.5 41.5 38.5
3 15 10.0 16.0 18.5
4 19 15.5 27.0 38.0
运行时测试-
在本节中,让我们测试迄今为止列出的解决性能问题的所有三种方法,包括^{}。In [24]: A = np.random.randint(0,9,(200,50))
In [25]: df = pd.DataFrame(A)
In [26]: %timeit df.groupby(df.index//2).mean() # @ayhan's solution
1000 loops, best of 3: 1.61 ms per loop
In [27]: %timeit pd.DataFrame(df.values.reshape(-1,2,df.shape[1]).mean(1))
1000 loops, best of 3: 317 µs per loop
In [28]: %timeit pd.DataFrame(np.einsum('ijk->ik',df.values.reshape(-1,2,df.shape[1]))/2.0)
1000 loops, best of 3: 266 µs per loop