Python 为多个数据帧和列应用函数

Python 为多个数据帧和列应用函数,python,pandas,dataframe,apply,Python,Pandas,Dataframe,Apply,您好,我正在使用两个数据帧,需要应用一个自定义函数,但我遇到以下错误:ValueError:(“序列的真值不明确。请使用a.empty、a.bool()、a.item()、a.any()或a.all()。,“发生在索引0处”)。我知道为什么会这样,但不知道如何解决这个问题 第一个数据框包含当前年度所有可用天数的列表: print(df_workable) Date workable_day inv_workable_day day month 1 2019-01-

您好,我正在使用两个数据帧,需要应用一个自定义函数,但我遇到以下错误:
ValueError:(“序列的真值不明确。请使用a.empty、a.bool()、a.item()、a.any()或a.all()。,“发生在索引0处”)
。我知道为什么会这样,但不知道如何解决这个问题

第一个数据框包含当前年度所有可用天数的列表:

print(df_workable)
          Date  workable_day  inv_workable_day  day  month
1   2019-01-02           1.0              22.0    2      1
2   2019-01-03           2.0              21.0    3      1
3   2019-01-04           3.0              20.0    4      1
6   2019-01-07           4.0              19.0    7      1
7   2019-01-08           5.0              18.0    8      1
..         ...           ...               ...  ...    ...
364 2019-12-31          20.0               1.0   31     12
第二个数据框包含有关某些日值和标志的数据

print(df)
       day_a1     wday_a1     iwday_a1       flag
0        24.0         4.0          6.0        2.1
1         NaN         NaN          NaN        NaN
3        31.0        22.0          1.0        2.2
4        27.0        18.0          5.0  3.3.2.1.3
26816    25.0        19.0          5.0          1
26817    31.0         NaN          NaN        3.2
我正在尝试应用一个函数,该函数将根据多种条件从任一数据帧返回日期(但为了简单起见,我只使用“this”和“that”)。这就是功能:

def rec_date(row):
    if row['flag'] == '2.1':
        if df_workable[df_workable['workable_day'] == int(row['wday_a1']) & df_workable['month'] == 1]['day'] <= dt.datetime.today().day:
            val = "this"
        else:
            val = "that"
    else:
        val = "Still missing"
    return val
(我正在传递
4
硬编码,因为它将是从df['wday_a1']传递的第一个值)。它的输出应该是
7
。与
dt.datetime.today().day
相比,该值为10,将返回true。我已经分别测试了这两个函数,它们确实返回了预期的输出。然而,当
在数据帧上应用这些函数时,问题就出现了,因为(我相信)上面解释的原因。
通过函数后,我希望得到以下结果:

df['rec_date'] = df.apply(rec_date,axis=1)
           day_a1     wday_a1     iwday_a1       flag         rec_date
    0        24.0         4.0          6.0        2.1             this
    1         NaN         NaN          NaN        NaN    Still missing
    3        31.0        22.0          1.0        2.2    Still missing
    4        27.0        18.0          5.0  3.3.2.1.3    Still missing
    26816    25.0        19.0          5.0          1    Still missing
    26817    31.0         NaN          NaN        3.2    Still missing

您的代码有两个小问题:

  • 您希望将两个条件与
    &
    组合在一起,但应将每个条件都用括号括起来,以便清楚地将它们分开:
    (x==…)&(y=…)
  • 该检查的结果具有一系列形式(其中只有一个观察值)。Python不确定如何将这一系列布尔值转换为一个布尔值,因为如果该系列有多个值,它不知道如何对它们进行聚合(如果所有值都为真,那么该系列应该只生成一个真值,或者如果至少有一个值为真,那么就足够了,…)。因此,您应该通过在支票中添加
    series.all()
    series.any()
    来澄清这一点
    那么,让我们把这句话分解一下:

    df_可工作[df_可工作['可工作天]==4和df_可工作['月]==1]['天]

  • df_可操作
    :完整的数据帧
  • df\u-workable[df\u-workable['workable\u-day']==int(行['wday\u-a1'])和df\u-workable['month']==1]
    :您正在根据
    workable\u-day
    month
    的特定值筛选数据帧。这将返回一个新的数据帧,其中包含整个数据帧的过滤结果
  • df_-awailable[df_-awailable['awailable\u-day']==int(行['wday\u-a1'])和df_-awailable['month']==1]['day']
    :这将获取步骤2中返回的数据帧并访问其
    ['day']
    列。这将返回一个对象,其中包含数据帧的
    day
    列的所有值

  • 这意味着,当你做
    df_可工作的[df_可工作的['wday_a1']==int(第['wday_a1']行)和df_可工作的['month']==1]['day']好吧,我明白你的意思。第一部分,返回一个具有单个值(因为每年只有一天/月组合)的序列,与单个值(即今天)相比,这确实提出了问题。此外,根据我的理解和给定的这个特殊情况(该系列只有1个值),使用
    。any()
    。all()
    将具有相同的效果,对吗?谢谢你的回答。你的陈述部分是正确的。提出问题的不是将序列与单个值进行比较。这部分会起作用,它只会返回一系列布尔值。问题是,当运行
    if-Series:
    时,它将失败,因为if语句需要一个布尔值。默认情况下,即使长度为1,pd.系列布尔值也不会转换为单个布尔值,因此您必须明确地告诉Python如何断言该系列是否为真。很高兴我能帮忙:)祝你好运!
    df['rec_date'] = df.apply(rec_date,axis=1)
               day_a1     wday_a1     iwday_a1       flag         rec_date
        0        24.0         4.0          6.0        2.1             this
        1         NaN         NaN          NaN        NaN    Still missing
        3        31.0        22.0          1.0        2.2    Still missing
        4        27.0        18.0          5.0  3.3.2.1.3    Still missing
        26816    25.0        19.0          5.0          1    Still missing
        26817    31.0         NaN          NaN        3.2    Still missing
    
    def rec_date(row):
        if row['flag'] == '2.1':
            if (df_workable[(df_workable['workable_day'] == int(row['wday_a1'])) & (df_workable['month'] == 1)]['day'] <= dt.datetime.today().day).all():
                val = "this"
            else:
                val = "that"
        else:
            val = "Still missing"
        return val
    
           day_a1  wday_a1  iwday_a1       flag       rec_date
    0        24.0      4.0       6.0        2.1           this
    1         NaN      NaN       NaN        NaN  Still missing
    3        31.0     22.0       1.0        2.2  Still missing
    4        27.0     18.0       5.0  3.3.2.1.3  Still missing
    26816    25.0     19.0       5.0          1  Still missing
    26817    31.0      NaN       NaN        3.2  Still missing