Python/Pandas:通过匹配的索引标准对 Dataframe 进行子集化

Posted

技术标签:

【中文标题】Python/Pandas:通过匹配的索引标准对 Dataframe 进行子集化【英文标题】:Python/Pandas: subset a Dataframe by matched index criteria 【发布时间】: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())

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

提前致谢!

【问题讨论】:

【参考方案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 并确保heightspecies 在那里。您是否尝试过其他解决方案并以这种方式合并您的列?【参考方案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

【讨论】:

以上是关于Python/Pandas:通过匹配的索引标准对 Dataframe 进行子集化的主要内容,如果未能解决你的问题,请参考以下文章

Python pandas 按多个索引范围切片数据帧

python--pandas切片

python pandas 如何去掉层次化索引

Python pandas用法

Python pandas数据框“日期”索引xlsx和csv中的不同格式

python--pandas合并与连接