【问题标题】:Having if or in list comprehension有 if 或 in 列表理解
【发布时间】:2021-02-23 16:32:52
【问题描述】:

在 python 3.7 中,有没有办法检查列表综合中的 2 个条件?

例如,如果我从以下开始,它只确保值不是 nan:

[1 if x is not np.nan else 0 for x in df["value"]]

但不是只检查值是否为 nan,我还想检查它是否为 nan 或等于“N”。比如:

[1 if (x is not np.nan) or (x != "N") else 0 for x in df["value"]]

实现这一点的最佳方法是什么?

感谢您的帮助。

【问题讨论】:

  • is not np.nan 不是您进行 NaN 检查的方式。
  • 没关系。更大的问题是条件表达式不是必需的。 bool 是 int 的子类,所以 True == 1 和 False == 0。您可以简单地编写[x is not np.nan or x != "N" for x in df["value"] 来获取布尔值列表。任何消耗列表期望 1s 和 0s 的东西都应该与 Trues 和 Falses 一样工作。
  • 这个语法应该可以正常工作。
  • @chepner:不是这样。大量 Pandas/NumPy 代码将布尔值与 int 区别对待(df 和 np 表明此代码几乎可以肯定同时使用这两个库(尽管不是很好))。例如,使用布尔数组索引 NumPy 数组与使用整数数组索引它的作用非常不同。
  • 另外,即使不存在 NaN 问题,or 也是错误的运算符。

标签: python list-comprehension nan


【解决方案1】:

首先,使用is 检查变量是否为NaN 可能很危险。实际上,这取决于您正在考虑哪种NaN:是来自math.nan 还是numpy.nan?

更健壮的解决方案是使用numpy.isnan / pandas.isna / math.isnan 方法。这是numpy.isnan 的示例:

import numpy as np
import math

numpy_nan = np.nan
math_nan = math.nan

print(np.isnan(numpy_nan)) # True
print(numpy_nan is np.nan) # True

print(np.isnan(math_nan)) # True
print(math_nan is np.nan) # False

如您所见,最后一个示例已被评估为False,而我认为您想要这个True


然后,回答您的问题:您可以在列表理解中添加许多不同的逻辑。但是,其他用户可能难以阅读,因此一般来说,一个好的做法是用逻辑定义一个小函数。列表推导会更容易理解:

import numpy as np
import pandas as pd

df = pd.DataFrame(
    {
        "value": [1, 0, np.nan]
    }
)

def is_valid(x):
    return not (np.isnan(x) or x == "N")

[1 if is_valid(x) else 0 for x in df["value"]] # [1, 1, 0]

最后,列表理解中的 if / else 在您的情况下似乎没用。实际上,您正在尝试将值列表转换为 1 / 0 列表,这类似于 True / False 列表,因此您可以简单地执行以下操作:

import numpy as np
import pandas as pd

df = pd.DataFrame(
    {
        "value": [1, 0, np.nan]
    }
)

def is_valid(x):
    return not (np.isnan(x) or x == "N")

[is_valid(x) for x in df["value"]] # [True, True, False]

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 2023-03-14
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多