【问题标题】:Filtering DataFrame with Multiple Criteria - Skipping Blank Criteria使用多个条件过滤 DataFrame - 跳过空白条件
【发布时间】:2021-07-23 05:56:11
【问题描述】:

我有一个数据框和 4 个用于过滤数据框的变量,这些变量由用户提供(国家/地区、公司类型等)。以下公式适用于所有 4 个变量均已设置的情况。

search_table = master_df.loc[(master_df['country'].isin(country)) 
                                    & (master_df['company_type'].isin(company_type))
                                    & (master_df['sector'].isin(sector))
                                    & (master_df['state'].isin(state))
                                    ]

但是,有时用户不会选择所有 4 个变量,代码将无法工作。如何编写代码以忽略 None 的变量而无需编写多个 If 语句?

【问题讨论】:

  • 用户如何声明这些列表?

标签: python pandas dataframe


【解决方案1】:

如果变量存在,那么您可以将它们组织在一个字典中并执行以下操作:

from functools import reduce
from operator import and_

variables = {'country': country, 'company_type': company_type,
             'sector': sector, 'state': state}

selection = reduce(and_, [master_df[v_str].isin(v)
                          for v_str, v in variables.items()
                          if v is not None])
search_table = master_df.loc[selection]

and_& 的函数版本(and_(a, b)a & b 相同)。而reduce通过and_依次聚合列表中的条件。

但是:至少一个变量必须不同于None。如果不能保证,您可以这样做:

selection = []
if any(variables.values()):
    selection = reduce(and_, [master_df[v_str].isin(v)
                              for v_str, v in variables.items()
                              if v is not None])
search_table = master_df.loc[selection]

如果不清楚变量是否存在,那么这样的事情可能会起作用:

variables = {'country', 'company_type', 'sector', 'state'}

selection = reduce(and_, [master_df[v].isin(globals()[v])
                          for v in variables
                          if globals().get(v, None) is not None])
search_table = master_df.loc[selection]

【讨论】:

  • 当我使用第二种情况时,我得到一个空数据框(所有变量都可以是无)。
  • 现在可以使用了。我刚刚从if v is not None 更改为if v。不完全确定两者之间的区别是什么,但非常感谢!!!
  • @pandashugger 不同之处在于:答案中的版本会阻止严格 None的变量,而您的版本会阻止真值为False的变量,这包括空列表。所以我的猜测是其中一个变量是[]?
  • 是的,我有一个空列表 - 非常感谢您的澄清
【解决方案2】:
search_table = master_df.loc[(master_df['country'].isin(country)) 
                                    & (master_df['company_type'].isin(company_type) if company_type else True)
                                    & (master_df['sector'].isin(sector) if sector else True)
                                    & (master_df['state'].isin(state) if state else True)
                                    ]

【讨论】:

  • 我认为由于... if ... else ... 语句的评估顺序(从左到右),这将崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 2014-08-12
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
相关资源
最近更新 更多