我有一个带有3级多索引列的pandas DataFrame。 底层总是两列,我想计算这两个列的差异,在前两个级别定义的每个组中。
import numpy as np
import pandas as pd
multi_idx = pd.MultiIndex.from_product([['A', 'B', 'C'], ['a', 'b'], ['L', 'S']],
names=['level_1', 'level_2', 'level_3'])
test_df = pd.DataFrame(np.random.randn(10, len(multi_idx)), columns=multi_idx)
所以,换句话说,我想在每组中计算'L' - 'S'。
这是我尝试使用pandas groupby:
net = test_df.groupby(level=['level_1', 'level_2'], axis=1, group_keys=False)\
.apply(lambda x: x.xs('L', axis=1, level='level_3', drop_level=True) -
x.xs('S', axis=1, level='level_3', drop_level=True))
但它返回所有NaN:
net
level_1 A B C
level_2 a b a b a b
level_3 L S L S L S L S L S L S
0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
我怎样才能做到这一点?
我在Python 3.4中使用pandas 0.21
答案 0 :(得分:1)
对我而言,它在pandas 0.23.0版本中工作,但我认为更好的是final List<Number> numberList = Arrays.asList(1, 2, 3D, 4D);
numberList.stream().collect(Collectors.toMap(Number::intValue, Function.identity()));
选择并减去:
xs
np.random.seed(10)
multi_idx = pd.MultiIndex.from_product([['A', 'B', 'C'], ['a', 'b'], ['L', 'S']],
names=['level_1', 'level_2', 'level_3'])
test_df = pd.DataFrame(np.random.randint(10, size=(10, len(multi_idx))), columns=multi_idx)
print (test_df)
level_1 A B C
level_2 a b a b a b
level_3 L S L S L S L S L S L S
0 9 4 0 1 9 0 1 8 9 0 8 6
1 4 3 0 4 6 8 1 8 4 1 3 6
2 5 3 9 6 9 1 9 4 2 6 7 8
3 8 9 2 0 6 7 8 1 7 1 4 0
4 8 5 4 7 8 8 2 6 2 8 8 6
5 6 5 6 0 0 6 9 1 8 9 1 2
6 8 9 9 5 0 2 7 3 0 4 2 0
7 3 3 1 2 5 9 0 1 0 1 9 0
8 9 2 1 1 0 0 5 9 0 4 6 6
9 0 2 3 3 2 6 0 5 1 3 6 5
df = test_df.xs('L', axis=1, level='level_3') - test_df.xs('S', axis=1, level='level_3')
print (df)
level_1 A B C
level_2 a b a b a b
0 5 -1 9 -7 9 2
1 1 -4 -2 -7 3 -3
2 2 3 8 5 -4 -1
3 -1 2 -1 7 6 4
4 3 -3 0 -4 -6 2
5 1 6 -6 8 -1 -1
6 -1 4 -2 4 -4 2
7 0 -1 -4 -1 -1 9
8 7 0 0 -4 -4 0
9 -2 0 -4 -5 -2 1
如果需要带有减去值的新列,一个可能的解决方案是net = test_df.groupby(level=['level_1', 'level_2'], axis=1, group_keys=False)\
.apply(lambda x: x.xs('L', axis=1, level='level_3', drop_level=True) -
x.xs('S', axis=1, level='level_3', drop_level=True))
print (net)
level_1 A B C
level_2 a b a b a b
level_3 L S L S L S L S L S L S
0 5 5 -1 -1 9 9 -7 -7 9 9 2 2
1 1 1 -4 -4 -2 -2 -7 -7 3 3 -3 -3
2 2 2 3 3 8 8 5 5 -4 -4 -1 -1
3 -1 -1 2 2 -1 -1 7 7 6 6 4 4
4 3 3 -3 -3 0 0 -4 -4 -6 -6 2 2
5 1 1 6 6 -6 -6 8 8 -1 -1 -1 -1
6 -1 -1 4 4 -2 -2 4 4 -4 -4 2 2
7 0 0 -1 -1 -4 -4 -1 -1 -1 -1 9 9
8 7 7 0 0 0 0 -4 -4 -4 -4 0 0
9 -2 -2 0 0 -4 -4 -5 -5 -2 -2 1 1
,不能删除drop_level=False
和S
级别,L
用于相同的新标签名称和rename
在一起:
concat