可能有一种更聪明的方法可以在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)
s = pd.Series([df1, df2, df3], index=idx)
# This causes an error
s.mean()
Run Code Online (Sandbox Code Playgroud)
我不会发布整个回溯,但主要的错误信息很有趣:
TypeError: Could not convert melt T_s
0 6 12
1 0 6
2 6 10 to numeric
Run Code Online (Sandbox Code Playgroud)
看起来数据框已经成功求和,但没有除以系列的长度.
但是,我们可以获取系列中数据帧的总和:
s.sum()
Run Code Online (Sandbox Code Playgroud)
返回
a b
0 6 12
1 0 6
2 6 10
Run Code Online (Sandbox Code Playgroud)
什么意思不是指总和时的工作?这是一个错误还是一个缺失的功能?这确实有效:
(df1 + df2 + df3)/3.0
Run Code Online (Sandbox Code Playgroud)
这样做:
s.sum()/3.0
a b
0 2 4.000000
1 0 2.000000
2 2 3.333333
Run Code Online (Sandbox Code Playgroud)
但这当然不理想.
你可以(正如@unutbu所建议的那样)使用分层索引,但是当你有一个三维数组时,你应该考虑使用" pandas Panel ".特别是当其中一个尺寸代表这种情况下的时间时.
该小组是经常被忽视,但它毕竟是在那里的名字熊猫的由来.(面板数据系统或类似的东西).
数据与原始数据略有不同,因此没有两个具有相同长度的维度:
df1 = pd.DataFrame([[1, 0], [1, 2], [2, 0], [2, 3]], columns=['a', 'b'])
df2 = df1 + 1
df3 = df1 + 10
Run Code Online (Sandbox Code Playgroud)
面板可以通过几种不同的方式创建,但其中一种来自dict.您可以使用索引和数据框创建dict:
s = pd.Panel(dict(zip(idx,[df1,df2,df3])))
Run Code Online (Sandbox Code Playgroud)
你正在寻找的意思只是在正确的轴上操作(在这种情况下,轴= 0):
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
Run Code Online (Sandbox Code Playgroud)
使用您的数据,sum(axis=0)返回预期结果.
编辑: 对于面板来说太晚了,因为分层索引方法已被"接受".我要说的是,如果数据在每个分组中被称为" 参差不齐 "且数据未知但数量不同,那么这种方法更可取.对于" 方形 "数据,该面板绝对是最佳选择,并且通过更多内置操作将显着提高速度.Pandas 0.15在多级索引方面有很多改进,但在现实世界的应用程序中仍有局限性和黑暗边缘情况.
当你定义s与
s = pd.Series([df1, df2, df3], index=idx)
Run Code Online (Sandbox Code Playgroud)
你得到一个带有DataFrames的系列作为项目:
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
Run Code Online (Sandbox Code Playgroud)
项目的总和是DataFrame:
In [78]: s.sum()
Out[78]:
a b
0 3 0
1 3 6
2 6 0
Run Code Online (Sandbox Code Playgroud)
但当你采取平均值时,nanops.nanmean称为:
def nanmean(values, axis=None, skipna=True):
values, mask, dtype, dtype_max = _get_values(values, skipna, 0)
the_sum = _ensure_numeric(values.sum(axis, dtype=dtype_max))
...
Run Code Online (Sandbox Code Playgroud)
请注意,在结果总和上调用_ensure_numeric(源代码).由于DataFrame不是数字,因此会引发错误.
这是一个解决方法.您可以将DataFrame连接到具有分层索引的新DataFrame,而不是将具有DataFrames的Series作为项目:
In [79]: s = pd.concat([df1, df2, df3], keys=idx)
In [80]: s
Out[80]:
a b
2010-01-01 00:00:00 0 1 0
1 1 2
2 2 0
2010-01-01 01:00:00 0 1 0
1 1 2
2 2 0
2010-01-01 02:00:00 0 1 0
1 1 2
2 2 0
Run Code Online (Sandbox Code Playgroud)
现在你可以采取sum和mean:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2102 次 |
| 最近记录: |