熊猫CSV:检查每一行是否为空

时间:2020-05-25 09:18:48

标签: python pandas csv

我想测试CSV文件的每一行,以了解某列是否为空,并据此更改另一列的值。

这就是我所拥有的:

df = df.replace(r'^\s*$', np.NaN, regex=True)
df['Multi-line'] = pd.Series(dtype=object)

for i, row in df.iterrows():
   if (row['Directory Number 1'] != np.NaN and row['Directory Number 2'] != np.NaN and row['Directory Number 3'] != np.NaN and row['Directory Number 4'] != np.NaN):
   df.at[i,'Multi-line'] = 'Yes'

如果2个“目录号X”或多个不为空,我希望“多行”列为“是”,并且如果1或0个“目录号X”不为空,则“多行”设为“否”。 这只是为了向您展示外观,但是在我的测试示例中,所有“多行”都设置为“是”,看来问题出在带有行值和np.nan的If条件中,但是我不知道如何检查行值是否为空。 谢谢您的帮助!

enter image description here enter image description here

2 个答案:

答案 0 :(得分:1)

我假设您执行了df = df.replace(r'^\s*$', np.NaN, regex=True) 之前。

然后,生成新列,运行:

df['Multi-line'] = df.apply(lambda row: 'Yes' if row.notna().sum() >= 2 else 'No', axis=1)

无需显式调用 iterrows ,因为 apply 安排了这样的操作 一个循环,为每一行调用传递的函数。

如果您的DataFrame还具有其他列,尤其是当它们可以 具有 NaN 值,则此lambda函数的应用应为 仅限于这四个感兴趣的列。

在这种情况下,运行:

cols = [ f'Directory Number {i}' for i in range(1, 5) ]
df['Multi-line'] = df[cols].apply(lambda row:
    'Yes' if row.notna().sum() >= 2 else 'No', axis=1)

请注意,建议的支票如if (row[s] != np.NaN): 在另一种解决方案中则是一种不好的方法,因为根据定义, NaN 不等于另一个 NaN ,因此您不能只比较两个 NaN

要进行检查,请尝试:

s = np.nan
s2 = np.nan
s != s2    # True
s == s2    # False

然后将所有“ true”字符串保存在 s 中,运行s = 'xx'并重复:

s != s2    # True
s == s2    # False

具有相同的结果。

答案 1 :(得分:-1)

您可以改用计数器

df = df.replace(r'^\s*$', np.NaN, regex=True)
df['Multi-line'] = pd.Series(dtype=object)

cnt=0;
str = ['Directory Number 1','Directory Number 2','Directory Number 3','Directory Number 4'];

for i, row in df.iterrows():
    for s in str:
        if (row[s] != np.NaN):
            cnt+=1;
    if (cnt>2):
        df.at[i,'Multi-line'] = 'Yes'
    else:
        df.at[i,'Multi-line'] = 'No'
    cnt=0;