Python 大熊猫指数级群比
我有下面的多索引数据帧,我想知道是否有一种方法可以在第二级索引上应用不同的函数Python 大熊猫指数级群比,python,pandas,group-by,Python,Pandas,Group By,我有下面的多索引数据帧,我想知道是否有一种方法可以在第二级索引上应用不同的函数 import pandas as pd # Creation df1 = pd.DataFrame([[1,2,1],[4,5,1],[4,5,2]], columns=["M1","M2","month"]) df1['var']="v1" df2 = pd.DataFrame([[1.5,2.5,1],[4.5,5.5,1],[1.5,1.5,2]], columns=["M1","M2","month"]) d
import pandas as pd
# Creation
df1 = pd.DataFrame([[1,2,1],[4,5,1],[4,5,2]], columns=["M1","M2","month"])
df1['var']="v1"
df2 = pd.DataFrame([[1.5,2.5,1],[4.5,5.5,1],[1.5,1.5,2]], columns=["M1","M2","month"])
df2['var']="v2"
df_all = pd.concat([df1,df2],join='outer')
# Final DataFrame
df_all_idx = df_all.set_index(["month","var"],inplace=False)
df_all_idx.sort_index(level=[0])
M1 M2
month var
1 v1 1.0 2.0
v1 4.0 5.0
v2 1.5 2.5
v2 4.5 5.5
2 v1 4.0 5.0
v2 1.5 1.5
通过groupby,我可以获得:
df_grp = df_all_idx.groupby(by=["month","var"]).sum()
M1 M2
month var
1 v1 5.0 7.0
v2 6.0 8.0
2 v1 4.0 5.0
v2 1.5 1.5
例如,我需要将sum()应用于v1值,并将自定义函数应用于v2值
谢谢想要这件作品吗
df_all_idx.xs('v1', level=1).sum(axis=1)
df_all_idx.xs('v2', level=1).apply(some_function, axis=1)
根据拆分、应用和恢复的建议,我提出了以下解决方案:
def myfunc(x):
return np.mean(x)
p1 = df_all_idx.loc[(slice(None), 'v1'), :].groupby(by=["month","var"]).sum()
p2 = df_all_idx.loc[(slice(None), 'v2'), :].groupby(by=["month","var"]).agg(myfunc)
pd.concat([p1,p2], join='outer').sort_index(level=[0])
返回我想要的结果:
M1 M2
month var
1 v1 5.0 7.0
v2 3.0 4.0
2 v1 4.0 5.0
v2 1.5 1.5
我认为这是这种情况下的最佳实践。我喜欢字典。因此,我会将聚合函数存储在字典中,并根据每个组的名称查找它们
import numpy
import pandas
aggregators = {
'v2': numpy.min
}
df1 = pandas.DataFrame(
[[1, 2, 1],[4, 5, 1],[4, 5, 2]],
columns=["M1", "M2", "month"]
).assign(var='v1')
df2 = pandas.DataFrame(
[[1.5,2.5,1], [4.5,5.5,1], [1.5,1.5,2]],
columns=["M1", "M2", "month"]
).assign(var='v2')
df = (
pandas.concat([df1, df2], join='outer')
.groupby(by=['month', 'var'])
.apply(lambda g: aggregators.get(g.name[-1], numpy.sum)(g))
[['M1', 'M2']]
)
那就是:
M1 M2
month var
1 v1 5.0 7.0
v2 1.5 2.5
2 v1 4.0 5.0
v2 1.5 1.5
这一行:.apply(lambda g:aggregators.get(g.name[-1],numpy.sum)(g))
有点复杂。它的作用如下:
.apply
在所有组中循环,并在lambda中运行它们name
属性,该属性是分组列的值g.name[-1]
是最后一个元素(v1、v2)aggregators.get(g.name[-1],numpy.sum)
查找要使用的函数,但如果找不到函数,则默认为numpy.sum
拆分数据帧,应用所需的函数,然后concatback@Wen严格地说,您不需要拆分它。我认为没有必要单独切片和执行聚合,并要求您在最后进行concat。@ScottBoston,如果我可以避免使用字典思考
if/elif/else
逻辑,我95%的时间都用字典time@PaulH使用dict是一个很好的工具,它可以改进pandas.concat([df1,df2],join='outer',keys=['v1','v2']),而您不需要assign@Wen这是一个与创建可复制示例相关的切向细节。