Python 为什么一系列数据帧意味着失败,而sum则不意味着失败,以及如何使其工作
在Python Pandas中,可能有一种更聪明的方法可以做到这一点,但下面的示例应该可以做到,但不起作用:Python 为什么一系列数据帧意味着失败,而sum则不意味着失败,以及如何使其工作,python,pandas,Python,Pandas,在Python Pandas中,可能有一种更聪明的方法可以做到这一点,但下面的示例应该可以做到,但不起作用: import pandas as pd import numpy as np df1 = pd.DataFrame([[1, 0], [1, 2], [2, 0]], columns=['a', 'b']) df2 = df1.copy() df3 = df1.copy() idx = pd.date_range("2010-01-01", freq='H', periods=3)
import pandas as pd
import numpy as np
df1 = pd.DataFrame([[1, 0], [1, 2], [2, 0]], columns=['a', 'b'])
df2 = df1.copy()
df3 = df1.copy()
idx = pd.date_range("2010-01-01", freq='H', periods=3)
s = pd.Series([df1, df2, df3], index=idx)
# This causes an error
s.mean()
我不会发布整个回溯,但主要错误消息很有趣:
TypeError: Could not convert melt T_s
0 6 12
1 0 6
2 6 10 to numeric
看起来数据帧已成功求和,但未除以序列的长度
但是,我们可以取系列中数据帧的总和:
s.sum()
返回
a b
0 6 12
1 0 6
2 6 10
为什么sum不意味着工作?这是一个bug还是一个缺失的特性?这确实有效:
(df1 + df2 + df3)/3.0
这也是:
s.sum()/3.0
a b
0 2 4.000000
1 0 2.000000
2 2 3.333333
但这当然并不理想 使用定义
s
时
s = pd.Series([df1, df2, df3], index=idx)
您将获得一个以数据帧为项目的系列:
In [77]: s
Out[77]:
2010-01-01 00:00:00 a b
0 1 0
1 1 2
2 2 0
2010-01-01 01:00:00 a b
0 1 0
1 1 2
2 2 0
2010-01-01 02:00:00 a b
0 1 0
1 1 2
2 2 0
Freq: H, dtype: object
项目的总和是一个数据帧:
In [78]: s.sum()
Out[78]:
a b
0 3 0
1 3 6
2 6 0
但当你采取中庸的态度时:
请注意,\u确保对结果和调用numeric
()。
由于数据帧不是数字,因此引发错误
这里有一个解决办法。而不是将数据帧作为项目制作一个系列,
您可以使用以下命令将数据帧连接到新的数据帧:
现在,您可以计算总和
和平均值
:
In [82]: s.sum(level=1)
Out[82]:
a b
0 3 0
1 3 6
2 6 0
In [84]: s.mean(level=1)
Out[84]:
a b
0 1 0
1 1 2
2 2 0
你可以(按Unutu建议)使用层次索引,但是当你有一个三维数组时,你应该考虑使用“”。特别是当其中一个维度表示时间时,如本例所示
面板经常被忽视,但毕竟它是熊猫这个名字的来源。(面板数据系统或类似系统) 数据与原始数据略有不同,因此没有两个长度相同的维度:df1 = pd.DataFrame([[1, 0], [1, 2], [2, 0], [2, 3]], columns=['a', 'b'])
df2 = df1 + 1
df3 = df1 + 10
面板可以通过两种不同的方式创建,但其中一种是从dict创建的。您可以通过以下方式从索引和数据帧创建dict:
s = pd.Panel(dict(zip(idx,[df1,df2,df3])))
您要寻找的平均值只是在正确的轴上操作的问题(在本例中,轴=0):
使用数据,sum(axis=0)
返回预期结果
编辑:对于面板来说,确定太迟了,因为分层索引方法已经“接受”。我要说的是,如果已知数据“参差不齐”,每个分组中的数字未知但不同,那么这种方法更可取。对于“方形”数据,面板是绝对可行的,并且随着内置操作的增加,速度将显著加快。Pandas 0.15在多级索引方面有许多改进,但在现实世界的应用程序中仍然存在局限性和暗边缘情况。不清楚它是否应该工作,但您可以应用以下功能:
s.apply(pd.DataFrame.mean)
这只是给出了每个组成数据帧的平均值。没错,面板上的计算速度明显快于分层数据帧上的计算速度。但是,面板上有哪些数据帧没有的额外内置操作呢set(dir(pan))-set(dir(df))
没有显示任何有趣的内容。另外,你能详细说明一下你提到的“限制和黑暗边缘案例”吗?这是我一次问两个问题的错。我将使用您的解决方案来解决我的问题,因为正如您所指出的,面板
解决方案是我给出的示例的正确解决方案。但我认为@unutbu解决了一个完整的问题,即到底是什么让我最初基于系列的代码无法工作。我非常感谢你的洞察力!这两个都应该在文档中!我还想补充一点,与分层索引版本不同,您现在还可以执行s_mean=np.mean(s,axis=0)
,或者sum、std,或者我猜任何在数组上工作的numpy函数。
df1 = pd.DataFrame([[1, 0], [1, 2], [2, 0], [2, 3]], columns=['a', 'b'])
df2 = df1 + 1
df3 = df1 + 10
s = pd.Panel(dict(zip(idx,[df1,df2,df3])))
s.mean(axis=0)
Out[80]:
a b
0 4.666667 3.666667
1 4.666667 5.666667
2 5.666667 3.666667
3 5.666667 6.666667