我想在我的DF中添加一个新级别(这样我就可以使用pd.reindex
来做其他事情)。我的DF基本上有这样的东西:
df = pd.DataFrame({('A','a'): [-1,-1,0,10,12],
('A','b'): [0,1,2,3,-1],
('A','c'): [-1,1,0,10,12],
('A','d'): [1,1,2,3,-1],
('B','a'): [-20,-10,0,10,20],
('B','b'): [-200,-100,0,-1,200],
('B','c'): [-20,-10,0,10,20],
('B','d'): [-200,-100,0,100,200]
})
##df
A B
a b c d a b c d
0 -1 0 1 1 -20 -200 -20 -200
1 -1 1 -1 1 -10 -100 -10 -100
2 0 2 0 2 0 0 0 0
3 10 3 10 3 10 -1 10 100
4 12 -1 12 -1 20 200 20 200
我想分配新的关卡L1
= a
+ b
和L2
= c
+ d
。我该怎么做?
所需的输出是
##df
A B
L1 L2 L1 L2
a b c d a b c d
0 -1 0 1 1 -20 -200 -20 -200
1 -1 1 -1 1 -10 -100 -10 -100
2 0 2 0 2 0 0 0 0
3 10 3 10 3 10 -1 10 100
4 12 -1 12 -1 20 200 20 200
编辑:目标是为了实现类似here中提到的内容。这意味着某些行对于相同的KEY将具有NA
s,具体取决于其他列的值。
例如。如果我想通过分别测试列a
和c
是否为负数来过滤列b
和d
:
##df
A B
L1 L2 L1 L2
a b c d a b c d
0 -1 0 1 1 NA NA NA NA
1 -1 1 -1 1 NA NA NA NA
2 0 2 0 2 0 0 0 0
3 10 3 10 3 NA NA 10 100
4 NA NA NA NA 20 200 20 200
答案 0 :(得分:3)
您需要使用array
创建新的map
,然后指定:
d = {'a':'L1','b':'L1','c':'L2','d':'L2'}
a = df.columns.get_level_values(1).map(lambda x: d[x])
print (a)
['L1' 'L1' 'L2' 'L2' 'L1' 'L1' 'L2' 'L2']
df.columns = [df.columns.get_level_values(0),a,df.columns.get_level_values(1)]
#same as
df.columns = pd.MultiIndex.from_arrays([df.columns.get_level_values(0),
df.columns.get_level_values(1).map(lambda x: d[x]),
df.columns.get_level_values(1)])
print (df)
A B
L1 L2 L1 L2
a b c d a b c d
0 -1 0 -1 1 -20 -200 -20 -200
1 -1 1 1 1 -10 -100 -10 -100
2 0 2 0 2 0 0 0 0
3 10 3 10 3 10 -1 10 100
4 12 -1 12 -1 20 200 20 200
第二个输出真的很复杂,对我而言:
#filter columns
idx = pd.IndexSlice
mask = df.loc[:, idx[:,:,['b','d']]] < 0
print (mask)
A B
L1 L2 L1 L2
b d b d
0 False False True True
1 False False True True
2 False False False False
3 False False True False
4 True True False False
#create mask to columns a,c
mask1 = mask.reindex(columns=df.columns)
mask1 = mask1.groupby(level=[0,1], axis=1).apply(lambda x: x.bfill(axis=1))
print (mask1)
A B
L1 L2 L1 L2
a b c d a b c d
0 False False False False True True True True
1 False False False False True True True True
2 False False False False False False False False
3 False False False False True True False False
4 True True True True False False False False
print (df.mask(mask1))
A B
L1 L2 L1 L2
a b c d a b c d
0 -1.0 0.0 -1.0 1.0 NaN NaN NaN NaN
1 -1.0 1.0 1.0 1.0 NaN NaN NaN NaN
2 0.0 2.0 0.0 2.0 0.0 0.0 0.0 0.0
3 10.0 3.0 10.0 3.0 NaN NaN 10.0 100.0
4 NaN NaN NaN NaN 20.0 200.0 20.0 200.0
使用reindex
和method='bfill'
的另一个解决方案,但是必须进行双重转置(我认为它是错误的 - 仅适用于MultiIndex
中的index
,而不适用于{{1在MultiIndex
):
columns