NumPythonic 的方法是将元素提取为带有 df.values 的 NumPy 数组,然后沿 axis=1 和 4 沿 axis=2 重塑为带有 2 元素的 3D 数组,并执行平均缩减沿着axis=1,最后转换回数据框,就像这样-
pd.DataFrame(df.values.reshape(-1,2,df.shape[1]).mean(1))
事实证明,您可以引入 NumPy 的非常高效的工具:np.einsum 来执行此操作 average-reduction 作为 sum-reduction 和 scaling-down 的组合,就像这样 -
pd.DataFrame(np.einsum('ijk->ik',df.values.reshape(-1,2,df.shape[1]))/2.0)
请注意,建议的方法假设行数可以被2 整除。
也如noted by @DSM,要保留列名,需要在转回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
运行时测试 -
在本节中,让我们测试迄今为止列出的所有三种方法来解决性能问题,包括@ayhan's solution with groupby。
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