计算表中每 x 行的平均值并创建新表
- 2025-03-05 09:18:00
- admin 原创
- 2
问题描述:
我有一张很长的数据表(约 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
预期均值表:
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
解决方案 1:
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
解决方案 2:
您可以使用pd.rolling()
创建滚动平均值来解决这个问题,然后使用iloc
df = df.rolling(2).mean()
df = df.iloc[::2, :]
请注意,第一个观察结果将会丢失(即滚动从顶部开始),因此请确保检查您的数据是否按您需要的方式排序。
解决方案 3:
NumPythonic 方法是使用 提取元素作为 NumPy 数组df.values
,然后重塑为具有沿和元素3D
的数组,并执行沿 的平均缩减,最后转换回数据框,如下所示 -2
`axis=14
axis=2`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
。
另外,为了保留列名,您需要在转换回 Dataframe 时noted by @DSM
添加,即 -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
解决方案 4:
df.set_index(np.arange(len(df)) // 2).mean(level=0)
解决方案 5:
就你的情况而言,由于你想对行进行平均,因此假设你的数据框名称是new
new = new.groupby(np.arange(len(new)) // 2).mean()
如果要计算列的平均值
new = new.groupby(np.arrange(len(new.columns)) // 2, axis=1).mean()
解决方案 6:
ValueError: Grouper and axis must be same length
当我尝试使用numpy
创建人工组时,我得到了。作为替代方案,您可以使用itertools
它将生成与您的 Dataframe 长度相等的迭代器:
SAMPLE_SIZE = 2
label_series = pd.Series(itertools.chain.from_iterable(itertools.repeat(x, SAMPLE_SIZE) for x in df.index))
sampled_df = df.groupby(label_series).mean()
- 2025年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)