【问题标题】:lambda row function with if else statement带有 if else 语句的 lambda 行函数
【发布时间】:2020-12-08 03:31:34
【问题描述】:

我有一个 pandas 数据框 df 和一个日期时间数组 holidays

df.head()

date    hour    count   Relative Humidity   Temperature Precipitation   dow
0   2019-07-01  0   672 57.64   71.8    0.0 Monday
1   2019-07-01  1   359 61.61   70.8    0.0 Monday
2   2019-07-01  2   197 61.63   69.8    0.0 Monday
3   2019-07-01  3   115 63.32   69.0    0.0 Monday
4   2019-07-01  4   168 67.91   67.9    0.0 Monday

df.dtypes

date                  object
hour                   int64
count                  int64
Relative Humidity    float64
Temperature          float64
Precipitation        float64
dow                   object
dtype: object

holidays

[datetime.date(2019, 9, 2), datetime.date(2019, 7, 4)]

我的目标是创建一个新列来指示日期是否为工作日,但以下 if else 语句会引发错误:

df['is_workday'] = df.apply(lambda row: False if (row['dow'] in ('Saturday', 'Sunday') | pd.to_datetime(row['date'],  format='%Y-%m-%d') in holidays) else True)

KeyError: 'dow'

什么可能导致这个问题?

【问题讨论】:

    标签: python pandas if-statement lambda


    【解决方案1】:

    默认情况下,df.apply(...) 应用于列。要在每一行上应用您的 lambda,请指定:

    df.apply(..., axis=1)
    

    除此之外,这看起来非常低效,并且可以在没有任何 lambda 的情况下变得更快。一种更有效的方法是将您的逻辑矢量化:

    cond_wkend = df['dow'].isin({'Saturday', 'Sunday'})
    cond_holdy = pd.to_datetime(df['date']).isin(holidays)
    
    df['is_workday'] = ~(cond_wkend | cond_holdy)
    

    【讨论】:

    • 谢谢。我尝试包括axis=0,但仍然得到同样的错误。可以做些什么来使这个语句更有效率?
    • 对不起,我的错,我更正了:我的意思是axis=1
    • axis = 1 会抛出一个稍微不同的错误:TypeError: unsupported operand type(s) for |: 'tuple' and 'Timestamp' - 但是使用 or 可以。 @Pierre 这里的效率可以做些什么?
    • 对,使用or 而不是|。前者是常规布尔值,后者是按位运算,例如在系列上。我只是在评论你最初的错误。
    • 查看我更新的答案。效率;对于大型 DataFrame,您会惊讶于矢量化操作的速度有多快。顺便说一句,在这种情况下,| 是正确的运算符(orSeries)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多