我有一个包含数据的Pandas DataFrame和另一个DataFrame,其中每一行都可以解释为数据的过滤器:

data_df = pd.DataFrame([{'a':i%10, 'b':i%15} for i in range(30)])

filter_df = pd.DataFrame({'a':[3,4,5], 'b0':[5,6,8], 'b1':[15,10,11]})
filter_df
    a   b0  b1
0   3   5   15
1   4   6   10
2   5   8   11

将意味着

pd.concat([
data_df[(data_df.a==3) & data_df.b.between(5,15)],
data_df[(data_df.a==4) & data_df.b.between(6,10)],
data_df[(data_df.a==5) & data_df.b.between(8,11)]
])

现在我需要的是一种将所有这些过滤器应用到data_df并得到结果DataFrame的方法.其中一种方法是使用Apply:

res = filter_df.apply(lambda x: data_df[(data_df.a==x['a']) & data_df.b.between(x['b0'], x['b1'])], axis=1)
res = pd.concat([x for x in res])

请注意,要使其正常工作,我必须连接一个结果列表,因为结果是一个包含每行返回值的Series,它可能是None、pd.Series或pd.DataFrame. 有没有更好的方法来做到这一点?我希望有类似.Reset_index()的内容,但似乎找不到正确的方法. 此外,如果有一种比申请更优雅/不同的方式,我会很高兴.实际上,data_df将在数百行或数百万行中,而Filter_df我预计将在1000行以下,但大多数情况下会超过10行,如果这对性能有影响的话

推荐答案

您可以合并和查询:

data_df.merge(filter_df, on='a', how='right').query('b0 <= b <= b1')

或者等效地,合并并锁定过滤器:

(data_df.merge(filter_df, on='a', how='right')
        .loc[lambda x: x['b'].between(x['b0'], x['b1'])]
)

输出:

   a   b  b0  b1
1  3  13   5  15
2  3   8   5  15
5  4   9   6  10
8  5  10   8  11

Python相关问答推荐

try 从网站获取表(ValueRight:如果使用所有纯量值,则必须传递索引)

正在设置字段.需要为假,因为错误列表索引必须是整数或切片,而不是字符串

如何循环循环的每个元素并过滤掉Python rame中的条件

如何从. text中进行pip安装跳过无法访问的库

在Python中添加期货之间的延迟

Odoo onchange for invoice_Status of sale事件.订单未触发

机器人与Pyton Minecraft服务器状态不和

强制venv在bin而不是收件箱文件夹中创建虚拟环境

添加包含中具有任何值的其他列的计数的列

Python daskValue错误:无法识别的区块管理器dask -必须是以下之一:[]

ModuleNotFound错误:没有名为Crypto Windows 11、Python 3.11.6的模块

可变参数数量的重载类型(args或kwargs)

按列分区,按另一列排序

在Pandas DataFrame操作中用链接替换'方法的更有效方法

从numpy数组和参数创建收件箱

根据二元组列表在pandas中创建新列

Asyncio:如何从子进程中读取stdout?

合并帧,但不按合并键排序

在matplotlib中删除子图之间的间隙_mosaic

在Python中从嵌套的for循环中获取插值