计算表中每x行的平均值并创建新表

Gnu*_*Gnu 16 python numpy python-3.x pandas

我有一个很长的数据表(大约200行乘50列)我需要创建一个代码,可以计算每两行的平均值和表中的每一列,最终输出是平均值的新表值.这在Excel中显然很疯狂!我使用python3,我知道一些类似的问题:这里,这里和这里.但这些都没有帮助,因为我需要一些优雅的代码来处理多个列并生成一个有组织的数据表.顺便说一句,我的原始数据表已经使用pandas导入并被定义为数据帧,但在pandas中找不到一种简单的方法.非常感谢帮助.

表(简称)的一个例子是:

a   b   c   d
2   50  25  26
4   11  38  44
6   33  16  25
8   37  27  25
10  28  48  32
12  47  35  45
14  8   16  7
16  12  16  30
18  22  39  29
20  9   15  47
Run Code Online (Sandbox Code Playgroud)

预期平均数表:

a    b     c     d
3   30.5  31.5  35
7   35    21.5  25
11  37.5  41.5  38.5
15  10    16    18.5
19  15.5  27    38
Run Code Online (Sandbox Code Playgroud)

ayh*_*han 21

您可以使用df.index//2(或@DSM指出,使用np.arange(len(df))//2- 以便它适用于所有索引)创建一个人工组,然后使用groupby:

df.groupby(np.arange(len(df))//2).mean()
Out[13]: 
      a     b     c     d
0   3.0  30.5  31.5  35.0
1   7.0  35.0  21.5  25.0
2  11.0  37.5  41.5  38.5
3  15.0  10.0  16.0  18.5
4  19.0  15.5  27.0  38.0
Run Code Online (Sandbox Code Playgroud)

  • 最好在 `np.arange(len(df))//2` 上分组,以防索引不是简单的 0,1,2.. 等。 (3认同)
  • 我发现一些接近的东西[这里](stackoverflow.com/questions/36810595/calculate-average-of-every-x-rows-in-a-table-and-create-new-table)但是你的答案如果非常优雅和紧凑。太感谢了!只是出于兴趣,df.index//2 中的第一个正斜杠意味着什么? (2认同)

see*_*spi 21

您可以使用pd.rolling()创建滚动平均值来解决此问题,然后使用iloc

df = df.rolling(2).mean() 
df = df.iloc[::2, :]
Run Code Online (Sandbox Code Playgroud)

请注意,第一个观察将丢失(即滚动从顶部开始),因此请确保检查您的数据是否按您需要的方式排序。

  • 这比以前的答案优雅得多。 (4认同)

Div*_*kar 6

NumPythonic的方法是将元素作为NumPy数组提取df.values,然后重新整形为3D包含2元素的数组,axis=1并4沿着axis=2它执行平均缩减axis=1,最后转换回数据帧,如下所示 -

pd.DataFrame(df.values.reshape(-1,2,df.shape[1]).mean(1))
Run Code Online (Sandbox Code Playgroud)

事实证明,你可以介绍与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)
Run Code Online (Sandbox Code Playgroud)

请注意,建议的方法假设行数可以被整除2.

另外noted by @DSM,为了保留列名,您需要columns=df.columns在转换回Dataframe时添加,即 -

pd.DataFrame(...,columns=df.columns)
Run Code Online (Sandbox Code Playgroud)

样品运行 -

>>> 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
Run Code Online (Sandbox Code Playgroud)

运行时测试 -

在本节中,让我们测试目前为止列出的所有三种方法,以解决性能问题,包括@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
Run Code Online (Sandbox Code Playgroud)


piR*_*red 5

df.set_index(np.arange(len(df)) // 2).mean(level=0)
Run Code Online (Sandbox Code Playgroud)