如何将 Pandas DataFrame 与 MultiIndex 列分组?
How to group Pandas DataFrame with MultiIndex columns?
我有一个 MultiIndex 列 Pandas DataFrame A:
foo
bar baz
s1_a 1 2
s1_b 3 4
s2_a 5 6
s2_b 7 8
我想根据来自另一个 DataFrame B 的键对数据进行分组:
key
s1_a 1
s1_b 1
s2_a 2
s2_b 2
对于没有 MultiIndex 的 DataFrame,我会这样做:
pd.merge(A, B, left_index=True, right_index=True).groupby('key').sum()
但这不适用于 MultiIndex。期望的结果是
foo
bar baz
1 4 6
2 12 14
我怎样才能做到这一点?
您可以在 merge
之后使用 pandas.concat
:
对级别进行子集化和恢复
C = pd.concat({'foo': (pd.merge(A['foo'], B, left_index=True, right_index=True)
.groupby('key')
.sum()
)
}, axis=1)
输出:
>>> C
foo
bar baz
key
1 4 6
2 12 14
注意。从技术上讲,您使用的代码应该使用 FutureWarning
,但是您丢失了 MultiIndex 而不是获取元组
>>> pd.merge(A, B, left_index=True, right_index=True).groupby('key').sum()
(foo, bar) (foo, baz)
key
1 4 6
2 12 14
FutureWarning: merging between different levels is deprecated and will be removed in a future version. (2 levels on the left,1 on the right)
系列可以直接传递给groupby
,石斑鱼会做适当的索引对齐,所以可以这样做:
A.groupby(B['key']).sum()
foo
bar baz
key
1 4 6
2 12 14
设置:
import numpy as np
import pandas as pd
idx = ['s1_a', 's1_b', 's2_a', 's2_b']
A = pd.DataFrame(
np.arange(1, 9).reshape((-1, 2)),
index=idx,
columns=pd.MultiIndex.from_product([['foo'], ['bar', 'baz']])
)
B = pd.DataFrame({'key': [1, 1, 2, 2]}, index=idx)
请注意,这在很多情况下都有效,但不如合并持久:
B
变体 1:
B = pd.DataFrame({'key': [1, 2, 2]}, index=['s1_a', 's1_b', 's2_b'])
key
s1_a 1 # No s2_a
s1_b 2
s2_b 2
A.groupby(B['key']).sum()
foo
bar baz
key
1.0 1 2
2.0 10 12
B
变体 2:
B = pd.DataFrame({'key': [1, 1, 2, 2]}, index=['s1_a', 's2_a', 's1_b', 's2_b'])
key
s1_a 1
s2_a 1 # s1_a/s2_a together
s1_b 2
s2_b 2 # s1_b/s2_b together
A.groupby(B['key']).sum()
foo
bar baz
key
1 6 8
2 10 12
我有一个 MultiIndex 列 Pandas DataFrame A:
foo
bar baz
s1_a 1 2
s1_b 3 4
s2_a 5 6
s2_b 7 8
我想根据来自另一个 DataFrame B 的键对数据进行分组:
key
s1_a 1
s1_b 1
s2_a 2
s2_b 2
对于没有 MultiIndex 的 DataFrame,我会这样做:
pd.merge(A, B, left_index=True, right_index=True).groupby('key').sum()
但这不适用于 MultiIndex。期望的结果是
foo
bar baz
1 4 6
2 12 14
我怎样才能做到这一点?
您可以在 merge
之后使用 pandas.concat
:
C = pd.concat({'foo': (pd.merge(A['foo'], B, left_index=True, right_index=True)
.groupby('key')
.sum()
)
}, axis=1)
输出:
>>> C
foo
bar baz
key
1 4 6
2 12 14
注意。从技术上讲,您使用的代码应该使用 FutureWarning
,但是您丢失了 MultiIndex 而不是获取元组
>>> pd.merge(A, B, left_index=True, right_index=True).groupby('key').sum()
(foo, bar) (foo, baz)
key
1 4 6
2 12 14
FutureWarning: merging between different levels is deprecated and will be removed in a future version. (2 levels on the left,1 on the right)
系列可以直接传递给groupby
,石斑鱼会做适当的索引对齐,所以可以这样做:
A.groupby(B['key']).sum()
foo
bar baz
key
1 4 6
2 12 14
设置:
import numpy as np
import pandas as pd
idx = ['s1_a', 's1_b', 's2_a', 's2_b']
A = pd.DataFrame(
np.arange(1, 9).reshape((-1, 2)),
index=idx,
columns=pd.MultiIndex.from_product([['foo'], ['bar', 'baz']])
)
B = pd.DataFrame({'key': [1, 1, 2, 2]}, index=idx)
请注意,这在很多情况下都有效,但不如合并持久:
B
变体 1:
B = pd.DataFrame({'key': [1, 2, 2]}, index=['s1_a', 's1_b', 's2_b'])
key
s1_a 1 # No s2_a
s1_b 2
s2_b 2
A.groupby(B['key']).sum()
foo
bar baz
key
1.0 1 2
2.0 10 12
B
变体 2:
B = pd.DataFrame({'key': [1, 1, 2, 2]}, index=['s1_a', 's2_a', 's1_b', 's2_b'])
key
s1_a 1
s2_a 1 # s1_a/s2_a together
s1_b 2
s2_b 2 # s1_b/s2_b together
A.groupby(B['key']).sum()
foo
bar baz
key
1 6 8
2 10 12