在多索引Pandas框架中过滤多个项目

ssm49v7z  于 2024-01-04  发布在  其他
关注(0)|答案(8)|浏览(138)

我有以下表格:

Area
NSRCODE  PBL_AWI          
CM       BONS             44705.492941
         BTNN            253854.591990
         FONG             41625.590370
         FONS             16814.159680
         Lake             57124.819333
         River             1603.906642
         SONS            583958.444751
         STNN             45603.837177
         clearcut        106139.013930
         disturbed       127719.865675
         lowland         118795.578059
         upland         2701289.270193
LBH      BFNN            289207.169650
         BONS           9140084.716743
         BTNI             33713.160390
         BTNN          19748004.789040
         FONG           1687122.469691
         FONS           5169959.591270
         FTNI            317251.976160
         FTNN           6536472.869395
         Lake            258046.508310
         River            44262.807900
         SONS           4379097.677405
         burn regen      744773.210860
         clearcut         54066.756790
         disturbed       597561.471686
         lowland       12591619.141842
         upland        23843453.638117

字符串
注意:NSRCODEPBL_AWI都是索引。
如何搜索列PBL_AWI中的值?例如,我想保留值['Lake', 'River', 'Upland']

vkc1a9a2

vkc1a9a21#

这是对所问问题的一个轻微变体的回答,可能会为其他人节省保存一些时间。如果您正在寻找与不知道确切值的标签相匹配的标签类型,您可以使用如下内容:

q_labels = [ label for label in df.index.levels[1] if label.startswith('Q') ]
new_df = df[ df.index.isin(q_labels, level=1) ]

字符串

at0kjp5o

at0kjp5o2#

您可以将get_level_values与布尔切片结合使用。

In [50]:

print df[np.in1d(df.index.get_level_values(1), ['Lake', 'River', 'Upland'])]
                          Area
NSRCODE PBL_AWI               
CM      Lake      57124.819333
        River      1603.906642
LBH     Lake     258046.508310
        River     44262.807900

字符串
同样的概念可以用许多不同的方式表达,例如df[df.index.get_level_values('PBL_AWI').isin(['Lake', 'River', 'Upland'])]
请注意,数据中有'upland',而不是'Upland'

mqkwyuun

mqkwyuun3#

另一种(可能更干净)的方法可能是这样的:

print(df[df.index.isin(['Lake', 'River', 'Upland'], level=1)])

字符串
参数level指定索引号(从0开始)或索引名称(此处为:level='PBL_AWI'

huus2vyu

huus2vyu4#

使用.loc的更简单的方法是

df.loc[(slice(None),['Lake', 'River', 'Upland']),:]

字符串
或系列

df.loc[(slice(None),['Lake', 'River', 'Upland'])]


slice(None)表示第一级索引没有过滤。我们可以使用值列表['Lake', 'River', 'Upland']过滤第二级索引

afdcj2ne

afdcj2ne5#

df.**filter(regex=...,axis=...)**更简洁,因为它同时适用于index=0和column=1轴。你不需要担心级别,你可以懒惰地使用regex。完整的index上的filter示例:

df.filter(regex='Lake|River|Upland',axis=0)

字符串


的数据
如果你转置它,并尝试在列上过滤(默认情况下轴=1),它也可以工作:

df.T.filter(regex='Lake|River|Upland')



现在,使用正则表达式,你也可以很容易地解决高地的大小写问题:

upland = re.compile('Upland', re.IGNORECASE)
df.filter(regex=upland ,axis=0)

这是读取上述输入表的命令:
第一个月

ngynwnxp

ngynwnxp6#

另外(来自here):

def filter_by(df, constraints):
    """Filter MultiIndex by sublevels."""
    indexer = [constraints[name] if name in constraints else slice(None)
               for name in df.index.names]
    return df.loc[tuple(indexer)] if len(df.shape) == 1 else df.loc[tuple(indexer),]

pd.Series.filter_by = filter_by
pd.DataFrame.filter_by = filter_by

字符串
......作为

df.filter_by({'PBL_AWI' : ['Lake', 'River', 'Upland']})


(未经测试的面板和更高的维度元素,但我希望它的工作)

2g32fytz

2g32fytz7#

也可以使用query

In [9]: df.query("PBL_AWI == ['Lake', 'River', 'Upland']")
Out[9]: 
                     Area
NSRCODE PBL_AWI          
CM      Lake     57124.82
        River     1603.91
LBH     Lake    258046.51
        River    44262.81

字符串
然而,由于大小写敏感,'高地'(小写)不会被找到。因此我建议使用fullmatch并设置case=False

In [10]: df.query("PBL_AWI.str.fullmatch('Lake|River|Upland', case=False).values")
Out[10]: 
                       Area
NSRCODE PBL_AWI            
CM      Lake       57124.82
        River       1603.91
        upland   2701289.27
LBH     Lake      258046.51
        River      44262.81
        upland  23843453.64

b4lqfgs4

b4lqfgs48#

对于简单的切片(对于DataFrames和Series),您也可以使用:来指定您想要该级别中的所有值。例如,我们不关心OP中第一个索引级别的值,因此我们使用:

df.loc[:, ['Lake', 'upland'], :]
#      ^                         <--- for first index level
#          ^^^^^^^^^^^^^^^^      <--- filter for the second index level
#                             ^  <--- select all columns (if any)

字符串

pd.IndexSlice[]

对于更复杂的切片,你可以使用pd.IndexSlice[]。例如,如果你也想选择列,那么使用pd.IndexSlice[]来指定哪部分是索引切片,哪部分是列选择。

df.loc[pd.IndexSlice[:, ['Lake', 'upland']], ['Area']]
#                    ^                               <--- slice for first index level
#                        ^^^^^^^^^^^^^^^^            <--- slice for second index level
#                                             ^^^^   <--- column selection


使用OP中给出的输入,我们得到以下结果:


的数据
您还可以按第一级、第二级和列进行选择。

df.loc[pd.IndexSlice['CM', ['Lake', 'upland']], ['Area']]


相关问题