【问题标题】:if, and, elif all included within an apply(lambda x:if, and, elif 都包含在 apply(lambda x:
【发布时间】:2021-09-28 17:12:30
【问题描述】:

我有以下代码:

data['ShortLongFlag'] = data['End DateTime'].apply(lambda x:
                                                   -1 if (x.month == 3 and x.date() in shortlongdates == True) else (1 if (x.month == 10 and x.date() in shortlongdates == True) else 0))

我想要做的是:

在我的数据框中创建一个新列,根据以下条件填充 -1、0 或 1:

  • -1 如果我的 datetime 列中的值的月份等于 3 并且日期在我的名为“shortlongdates”的日期列表中
  • 1 如果我的日期时间列中的值的月份等于 10 并且日期在我的名为“shortlongdates”的日期列表中
  • 0 否则

现在所有值都在新列中输出为 0...为什么?

【问题讨论】:

  • 没有理由不在这里创建适当的函数,而是尝试将内容压缩成lambda
  • 你能分享一些数据吗?
  • @roganjosh 你有什么建议吗?或者你能解释一下为什么 lambda 不起作用?对我来说并没有那种压缩感
  • lambda 是函数。见*.com/questions/16501/what-is-a-lambda-function/…问题是我们必须疯狂滚动才能阅读你的功能
  • @SlowlyLearning 问题不在于我们不知道如何滚动;)而是将所有内容放在一行中本质上是不可读的。

标签: python pandas date datetime lambda


【解决方案1】:

这个问题的原因是chaining comparison operators

比较可以任意链接,例如,x

比较,包括成员资格测试和身份测试have same precedence

x.month == 3 and x.date() in shortlongdates == True

相同
x.month == 3 and x.date() in shortlongdates and shortlongdates == True

注意可以写成x.month == 3 and x.date() in shortlongdates,也可以用括号。然而,正如 cmets 中所述,这个 lambda 最好写成常规函数。

def replace_value(x):
    if x.date() in shortlongdates:
        return {3:-1, 10:1}.get(x.month, 0)
    return 0

如果您坚持,我会留给您将其转换回 [更简单的] lambda。

【讨论】:

  • 虽然我喜欢你最后的 dict 简化,但可能值得指出它是如何工作的
【解决方案2】:

所以我们有这个不可读的东西:

lambda x: -1 if (x.month == 3 and x.date() in shortlongdates == True) else (1 if (x.month == 10 and x.date() in shortlongdates == True) else 0)

让我们把它写成一个标准函数:

def filterfn(x):
    if x.month == 3 and x.date() in shortlongdates:
        return -1
    elif x.month == 10 and x.date() in shortlongdates:
        return 1
    else:
        return 0

删除一些陌生的测试(冗余 == True)和括号。

x.date() 真的是可调用的吗?应该是x.date? 如果没有看到您的datalistofdates,就不可能说这会如何失败,但至少我们可以看到它在做什么。

【讨论】:

  • 以防 OP 不确定,在定义 filterfn 后,如上,它可以如下使用:data['ShortLongFlag'] = data['End DateTime'].apply(filterfn) 即,你之前有 lambda,现在你只需说 filterfn .
  • x.date() in shortlongdates 进行两次评估毫无意义;如果为假,您甚至可以在检查 x.month 之前立即返回 0。
  • @chepner 这个答案距离理想还有很长的路要走。我可能会删除它。它只是将 lambda 的应该作为 fn 来呈现。我故意避免简化它,等待 OP 返回更多信息。 Buran 在下面有正确(简化)的答案