簡體   English   中英

通過多索引列切片謂詞從DataFrame篩選行

[英]Filter rows from DataFrame by multi-index column slice predicate

我有一個數據框,其中包含定義為以下內容的列的多索引:

import numpy as np
import pandas as pd
index = range(4)
columns = pd.MultiIndex.from_product([
    ['A0', 'B0'],
    ['A1', 'B1'],
    ['A2', 'B2']
])

data = np.random.rand(len(index), len(columns))
df = pd.DataFrame(data, index=index, columns=columns)

這給了我類似的東西:

         A0                                      B0                              
         A1                  B1                  A1                  B1          
         A2        B2        A2        B2        A2        B2        A2        B2
0  0.523564  0.270243  0.881117  0.760946  0.687436  0.318483  0.963247  0.161210
1  0.141363  0.563427  0.242174  0.966277  0.382161  0.486944  0.417305  0.513510
2  0.832275  0.036995  0.510963  0.112446  0.069597  0.490321  0.022453  0.643659
3  0.601649  0.705902  0.735125  0.506853  0.666612  0.533352  0.484133  0.069325

我現在想過濾所有B2列的值低於閾值(例如0.05 我做了以下事情:

df_filtered = df[df.loc[:, (slice(None), slice(None), 'B2')] < 0.05]

但這給了我以下幾點:

   A0                    B0            
   A1            B1      A1      B1    
   A2        B2  A2  B2  A2  B2  A2  B2
0 NaN NaN       NaN NaN NaN NaN NaN NaN
1 NaN NaN       NaN NaN NaN NaN NaN NaN
2 NaN  0.036995 NaN NaN NaN NaN NaN NaN
3 NaN NaN       NaN NaN NaN NaN NaN NaN

這不是我想要的,因為:

  • 該行的值以某種方式映射到NaN 我想保留原始的行內容。
  • 返回所有行。 我只希望B2值中的任何一個低於0.05 ,在此cas中只有index=2行。

我該如何實現?

使用DataFrame.any檢查每列至少一個True ,並添加reindex來追加缺少的MultiIndex級別:

np.random.seed(456)

import numpy as np
import pandas as pd
index = range(4)
columns = pd.MultiIndex.from_product([
    ['A0', 'B0'],
    ['A1', 'B1'],
    ['A2', 'B2']
])

data = np.random.rand(len(index), len(columns))
df = pd.DataFrame(data, index=index, columns=columns)
print (df)
         A0                                      B0                      \
         A1                  B1                  A1                  B1   
         A2        B2        A2        B2        A2        B2        A2   
0  0.248756  0.163067  0.783643  0.808523  0.625628  0.604114  0.885702   
1  0.181105  0.150169  0.435679  0.385273  0.575710  0.146091  0.686593   
2  0.569999  0.645701  0.723341  0.680671  0.180917  0.118158  0.242734   
3  0.360068  0.146042  0.542723  0.857103  0.200212  0.134633  0.213594   



         B2  
0  0.759117  
1  0.468804  
2  0.008183  
3  0.973156 

mask = ((df.loc[:, (slice(None), slice(None), 'B2')] < 0.05)
           .any()
           .reindex(df.columns, fill_value=False))
print (mask)
A0  A1  A2    False
        B2    False
    B1  A2    False
        B2    False
B0  A1  A2    False
        B2    False
    B1  A2    False
        B2     True
dtype: bool

df = df.loc[:, mask]
print (df)
         B0
         B1
         B2
0  0.759117
1  0.468804
2  0.008183
3  0.973156

對於行,解決方案更簡單-使用DataFrame.anyaxis=1來檢查每行至少一個True

mask = (df.loc[:, (slice(None), slice(None), 'B2')] < 0.05).any(axis=1)
print (mask)
0    False
1    False
2     True
3    False
dtype: bool

df = df[mask]
print (df)
         A0                                      B0                      \
         A1                  B1                  A1                  B1   
         A2        B2        A2        B2        A2        B2        A2   
2  0.569999  0.645701  0.723341  0.680671  0.180917  0.118158  0.242734   



         B2  
2  0.008183  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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