【问题标题】:Python/Pandas: subset a Dataframe by matched index criteriaPython/Pandas:通过匹配的索引标准对 Dataframe 进行子集化
【发布时间】:2020-06-23 14:41:43
【问题描述】:

我是 Python 新手(习惯于与表弟 R 一起编码),但我仍然对 pandas 有所了解。有一个incredibly helpful, related post.,但我希望通过第二个数据集中定义的标准来过滤(),而不是通过一组数字进行过滤。

让我们做一些玩具数据:

import pandas as pd

pets = [['foxhound', 'dog', 20], ['husky', 'dog', 25], ['GSD', 'dog', 24],['Labrador', 'dog', 23],['Persian', 'cat', 7],['Siamese', 'cat', 6],['Tabby', 'cat', 5]]

df = pd.DataFrame(pets , columns = ['breed', 'species','height']).set_index('breed')

TooBigForManhattan = [['dog', 22],['cat', 6]]

TooBig = pd.DataFrame(TooBigForManhattan, columns = ['species','height']).set_index('species')

我试图通过选择小于或等于TooBig() 值的品种来对df() 进行子集化。我的伪代码如下:

df.groupby(['breed','species']).filter(lambda x : (x['height']<='TooBig Cutoff by Species').any())

我正在处理的数据是包含大约一百个标准的数千个条目,因此任何帮助定义可以在该规模上工作的解决方案都会非常有帮助。

提前致谢!

【问题讨论】:

    标签: python pandas filter group-by


    【解决方案1】:

    通过单个列上的连接,您可以map 每个物种的高度并检查 DataFrame 中的值是否更小。

    df[df['height'] <= df['species'].map(dict(TooBigForManhattan))]
    
             species  height
    breed                   
    foxhound     dog      20
    Siamese      cat       6
    Tabby        cat       5
    

    这里有一些关于中间步骤的更多细节。

    # List of lists becomes this dict
    dict(TooBigForManhattan)
    #{'cat': 6, 'dog': 22}
    
    # We use this Boolean Series to slice the DataFrame
    df.height <= df.species.map(dict(TooBigForManhattan))
    #breed
    #foxhound     True
    #husky       False
    #GSD         False
    #Labrador    False
    #Persian     False
    #Siamese      True
    #Tabby        True
    #dtype: bool
    

    【讨论】:

    • 不错,只是映射器是 1 列 df ,df[df['height'] &lt;= df['species'].map(TooBig.squeeze())]
    • 非常感谢您展示这些步骤。我使用df[df['height'] &lt;= df['species'].map(dict(TooBigForManhattan))] 在我的实际数据上得到一个 KeyError,但是通过中间步骤,我得到一个干净的布尔输出。如何从具有 True 和 False 的大 df() 到最终输出?
    • @EBITDAN 嗯,打印df.columns 并确保height 和species 在那里。您是否尝试过其他解决方案并以这种方式合并您的列?
    【解决方案2】:

    我相信你需要merge,你可以使用df.query

    out = (df.merge(TooBig,left_on='species',right_index=True,suffixes=('','_y'))
             .query("height<=height_y").loc[:,df.columns])
    print(out)
    

    或类似:

    out = df.merge(TooBig,left_on='species',right_index=True,suffixes=('','_y'))
    out = out[out['height']<=out['height_y']].reindex(columns=df.columns)
    print(out)
    

             species  height
    breed                   
    foxhound     dog      20
    Siamese      cat       6
    Tabby        cat       5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 2015-05-18
      • 2018-09-19
      • 2020-04-27
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      相关资源
      最近更新 更多