熊猫Multiindex和Groupby

时间:2018-05-18 08:55:28

标签: python pandas pandas-groupby multi-index

我有一个带有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

1 个答案:

答案 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=FalseS级别,L用于相同的新标签名称和rename在一起:

concat