我想测试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条件中,但是我不知道如何检查行值是否为空。 谢谢您的帮助!
答案 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;