[英]Adding level to middle of DF in Pandas
我想向我的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
編輯:目標是實現類似於此處要求的功能。 這意味着某些行的同一KEY將具有NA
,具體取決於其他列的值。 例如,如果我想通過分別測試列b
和d
是否為負數來過濾列a
和c
:
##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
您需要使用map
創建新array
,然后分配:
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
僅MultiIndex
於index
MultiIndex
,而不MultiIndex
於columns
MultiIndex
):
idx = pd.IndexSlice
mask = df.loc[:, idx[:,['b','d']]] < 0
print (mask)
A B
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
mask1 = mask.T.reindex(df.columns, method='bfill').T
print (mask1)
A B
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
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.