我有一个长数据表(大约200行乘50列)我需要创建一个代码,可以计算每两行的平均值和表中的每一列,最终输出是一个新表平均值。这在Excel中显然很疯狂!我使用python3,我知道一些类似的问题:here,here和here。但这些都没有帮助,因为我需要一些优雅的代码来处理多个列并生成一个有组织的数据表。顺便说一句,我的原始数据表已经使用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
答案 0 :(得分:20)
您可以使用df.index//2
创建一个人工组(或者使用np.arange(len(df))//2
指示@DSM - 以便它适用于所有索引)然后使用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
答案 1 :(得分:6)
NumPythonic方法是使用df.values
将元素提取为NumPy数组,然后重构为3D
数组2
元素axis=1
和4
沿着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
整除。
同样为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
答案 2 :(得分:4)
df.set_index(np.arange(len(df)) // 2).mean(level=0)
答案 3 :(得分:1)
您可以使用iloc
创建滚动平均值来解决此问题,然后使用df = df.rolling(2).mean()
df = df.iloc[::2, :]
pid = /run/stunnel.pid
output = /etc/stunnel/stunnel.log
[Redis server]
cert = /etc/stunnel/ABC_private.pem
accept = xxx.xx.160.77:26280
connect = 127.0.0.1:26280
[Client XYZ Redis Server]
client=yes
cert = /etc/stunnel/XYZ_private.pem
accept = 127.0.0.1:8000
connect = xxx.xx.161.78:6480
# SENTINEL SERVERS
[Client 123 Sentinel Server]
client=yes
cert = /etc/stunnel/123_private.pem
accept = 127.0.0.1:8001
connect = xxx.xx.160.77:26280
请注意,第一次观察将会丢失(即滚动从顶部开始)
答案 4 :(得分:1)
在您的情况下,由于您想对行求平均值,假设您的数据框名称为 new = new.groupby(np.arange(len(new)) // 2).mean()
new = new.groupby(np.arrange(len(new.columns)) // 2, axis=1).mean()
如果想对列求平均值
DoubleProperty checkboxFontSize = new SimpleDoubleProperty(10);
checkboxFontSize.bind((dryLeafGridPane.widthProperty().divide(36)));
答案 5 :(得分:0)
当我尝试使用 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()