簡體   English   中英

在熊貓的DF中間添加等級

[英]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 + bL2 = 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 ,具體取決於其他列的值。 例如,如果我想通過分別測試列bd是否為負數來過濾列ac

##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

帶有reindexmethod='bfill'另一種解決方案,但有必要進行兩次轉置(我認為這是MultiIndexMultiIndexindex MultiIndex ,而不MultiIndexcolumns 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM