【问题标题】:Include an if statement when filtering a dataframe by other criteria按其他条件过滤数据框时包含 if 语句
【发布时间】:2021-05-21 03:37:08
【问题描述】:

我有一个大约 600 行的数据框,可以追溯到 2015 年:

ID   Year  Trap                             SVL
1    2020  ['P90', 'R81']                   78
2    2019  ['P3']                           56
3    2018  ['P22', 'R1', 'R11', 'PR22']     45

我需要搜索/过滤手头的个体(蜥蜴),已知变量是 Trap 和 SVL(鼻子到通风口的长度,单位为 mm) - 例如,当前的蜥蜴可能来自 Trap == 'R1' 及其SVL >= 45,则搜索应返回 ID 3。在 2021 年,蜥蜴的 SVL = 75(它每年增长约 10 毫米,我添加 +/- 5 毫米以表示测量误差)。

我将标准保存在一个字典中:

dict_choice = {'Trap': ['R1'],
               'SVL': (70.0, 80.0)}

我的正常搜索如下:

newdf = df.loc[df.Trap.map(set(dict_choice['Trap']).issubset) &
               ( (df['SVL'] >= dict_choice['SVL'][0]) & (df['SVL'] <= dict_choice['SVL'][1]))

我可以将年份作为搜索条件吗? 为了尽量减少匹配蜥蜴的数量,我需要添加一个过滤器,从 2021 年开始,我们每年都会查看少 5 毫米的 SVL。例如蜥蜴 ID 3 在 2018 年是 45 毫米,这意味着到 2021 年它应该是 75 毫米,但是要匹配它,我们只需要查看 SVL

if @year == 2021: 
   search all where @Trap IN dict_choice['Trap'] AND ((df['SVL'] >= dict_choice['SVL'][0]) & (df['SVL'] <= dict_choice['SVL'][1]))
elif @year == 2020:
   search all where @Trap IN dict_choice['Trap'] AND ((df['SVL'] >= dict_choice['SVL'][0]) & (df['SVL'] <= dict_choice['SVL'][1]-5))
elif @year == 2019:
   search all where @Trap IN dict_choice['Trap'] AND ((df['SVL'] >= dict_choice['SVL'][0]) & (df['SVL'] <= dict_choice['SVL'][1]-10))
(...)

TL;DR:我可以在按其他条件过滤数据帧时包含 if 语句吗?

【问题讨论】:

    标签: python pandas dataframe search


    【解决方案1】:

    我能否建议您在测试标准中添加一个“固定”年份,例如

    dict_choice = {'Trap': ['R1'],
                   'SVL': (70.0, 80.0),
                   'Year': [2020]}
    

    那么你可以在代码本身中为测试提供线性余量

    import pandas as pd
    data = { 'ID': [1,2,3],
             'Year' : [2020,2019,2018],
             'Trap' : [['P90', 'R81'], ['P3'] ,['P22', 'R1', 'R11', 'PR22']],
             'SVL' : [78,56,45]}
    
    df = pd.DataFrame(data)
    

    如上获取数据框

    dict_choice = {'Trap': ['R81'],
                   'SVL': (70.0, 80.0),
                   'Year': [2018]}
    

    是带有测试基准年的增强查询

    newdf = df.loc[df.Trap.map(set(dict_choice['Trap']).issubset) &
                   ( (df['SVL'] >= dict_choice['SVL'][0]) & 
                     (df['SVL'] <= dict_choice['SVL'][1] + 5.0 * (df['Year'] - dict_choice['Year'])))]
    

    那么这个查询在支票中内置了线性余量。

    请注意,如果年份早于基准年,查询允许蜥蜴生长,如果落后则收缩。

    也许你应该在两边都有移动,但它只是遵循查询的模式(如下)

    newdf = df.loc[df.Trap.map(set(dict_choice['Trap']).issubset) &
                   ( (df['SVL'] >= dict_choice['SVL'][0] + 5.0 * (df['Year'] - dict_choice['Year'])) & 
                     (df['SVL'] <= dict_choice['SVL'][1] + 5.0 * (df['Year'] - dict_choice['Year'])))]
    

    【讨论】:

    • 感谢您的彻底回复和通读我的问题。事情是我不能将一年作为变量传递,因为它不知道查询何时开始,它是从结果数据中读取的。我放弃了,作为一种解决方法,计算了今天日期的“预计 SVL”,然后在长度之间进行简单过滤。
    猜你喜欢
    • 2021-06-19
    • 2016-02-29
    • 2019-10-15
    • 2011-05-27
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    相关资源
    最近更新 更多