代码之家  ›  专栏  ›  技术社区  ›  Sembei Norimaki

按索引名筛选数据帧行

  •  3
  • Sembei Norimaki  · 技术社区  · 6 年前

    我有一个数据框,我想根据元素的索引名在其中放置元素

                   col1  col2
    entry_1          10    11
    entry_2_test     12    13
    entry_3          14    15
    entry_4_test     16    17
    

    基本上我想放弃那些以“U测试”结尾的

    我知道如何选择他们:

    df.filter(like='_test', axis=0)
    
                   col1  col2
    entry_2_test     12    13
    entry_4_test     16    17
    

    然后我可以得到这些索引:

    df.filter(like='_test', axis=0).index
    
    entry_2_test
    entry_4_test
    

    最后,我可以删除这些索引,并用筛选的索引覆盖我的数据帧。

    df = df.drop(df.filter(like='_test', axis=0).index)
    df
    
                   col1  col2
    entry_1          10    11
    entry_3          14    15
    

    我的问题是,这是正确的过滤方式,还是有一个更高效的专用函数来实现?

    3 回复  |  直到 6 年前
        1
  •  6
  •   EdChum Larry    6 年前

    您可以将 str.endswith :

    In[13]:
    df.loc[~df.index.str.endswith('_test')]
    
    Out[13]: 
             col1  col2
    entry_1    10    11
    entry_3    14    15
    

    或者对最后5个字符进行切片,并使用 != :

    In[13]:
    df.loc[df.index.str[-5:]!='_test']
    
    Out[18]: 
             col1  col2
    entry_1    10    11
    entry_3    14    15
    

    仍然可以使用 filter 通过传递regex模式筛选出不以 '_test' :

    In[25]:
    df.filter(regex='.*[^_test]$', axis=0)
    
    Out[25]: 
             col1  col2
    entry_1    10    11
    entry_3    14    15
    

    正如@user3483203指出的,最好使用以下regex:

    df.filter(regex='.*(?<!_test)$', axis=0)
    
        2
  •  3
  •   BENY    6 年前

    filter regex

    df.filter(regex='.*[^_test]$', axis=0)
    Out[274]: 
             col1  col2
    entry_1    10    11
    entry_3    14    15
    
        3
  •  2
  •   jpp    6 年前

    您可以使用列表理解并将布尔值列表馈送给 pd.DataFrame.loc .

    虽然这看起来可能是反模式的,但实际上更有效,因为熊猫串方法没有特别优化:

    df2 = pd.concat([df]*10000)
    
    %timeit df2.loc[[i[-5:] == '_test' for i in df2.index]]    # 11.7 ms per loop
    %timeit df2.loc[[i.endswith('_test') for i in df2.index]]  # 13.3 ms per loop
    %timeit df2[~(df2.index.str[-5:] == '_test')]              # 22.1 ms per loop
    %timeit df2[~df2.index.str.endswith('_test')]              # 21.7 ms per loop