从列表或字典中写出任意大小的布尔表达式

Write a Boolean expression of arbitrary size from a list or dictionary

我正在处理 pandas 数据帧,这些数据帧具有一些统一的列标签模式,但列数是任意的。

例如,下面的 df 包含列 col_names,列的一个特殊子集,以及与这些特殊列对应的过滤条件。它们通过索引或字典链接,任您选择。

col_names = ['col1','col2','col3','xyz.1','xyz.2','xyz.3']
relevant_col_names = ['xyz.1', 'xyz.2', 'xyz.3']
filter_criteria = [something1, something2, something3]

我想获取子集数据帧,其中 'xyz.1' == something1 & 'xyz.2' == something2 & 'xyz.3' ==something3

我通常会这样做:

whatIwant = df.loc[df['xyz.1']==something1 & df['xyz.2']==something2 & df['xyz.3']==something3]

问题是我需要能够为任意数量的 'xyz' 列 编写该表达式,而无需手动编写上述表达式的代码。

例如,如果 df 恰好有 5 个相关列,如下所示:

['col1','col2','col3','xyz.1','xyz.2','xyz.3','xyz.4','xyz.5']

然后我需要自动写这样的东西:

whatIwant = df.loc[df['xyz.1']==something1 & df['xyz.2']==something2 & df['xyz.3']==something3 & df['xyz.4']==something4 & df['xyz.5']==something5]

有没有一种方法可以根据列表或字典(或其他东西)编写任意长度的布尔表达式,并在其中对其中的所有内容进行 ANDing?

我不知道如何为 google 表述这个问题。它似乎与列表和字典理解、表达式合成或其他内容有关。即使知道表达这个问题的正确方式,如何为 Whosebug 标记这个问题,and/or 我应该 google 也会很有帮助。谢谢!

假设你有一个列表中的所有“东西”,你可以这样做:

import functools
import operator
import pandas as pd

df = pd.DataFrame.from_dict({
    "abc": (1, 2, 3),
    "xyz.1": (4, 2, 7),
    "xyz.2": (8, 5, 5)
})
targets = [2, 5]

filtered_dfs = (df[f"xyz.{index + 1}"] == target for index, target in enumerate(targets))
filtered_df = df.loc[functools.reduce(operator.and_, filtered_dfs)]

print(filtered_df)

我们通过 df[f"xyz.{index + 1}"] == targetfiltered_dfs 中的 df 上构造每个过滤器。对于 targets 的第一次迭代,这将是 df["xyz.1"] == 2。对于第二次迭代,它将是 df["xyz.2"] == 5.

然后我们将所有这些过滤器与 functools.reduce(operator.and_, filtered_dfs) 结合起来,这就像 filtered_df_1 & filtered_df_2 & ....

我们最终通过 df.loc 将过滤器应用于数据框,这给出了此处在 xyz.1 中具有 2 且在 [=24= 中具有 5 的行].输出为:

   abc  xyz.1  xyz.2
1    2      2      5