假设我的数据帧的第二列包含整数列表:
df = pd.DataFrame({"col_1":[1,2,3,4,5],"col_2":[[1,2],np.nan,[3,5,9],[2],[8,5]],"col_3":np.nan})
输出:
col_1 col_2 col_3
0 1 [1, 2] NaN
1 2 NaN NaN
2 3 [3, 5, 9] NaN
3 4 [2] NaN
4 5 [8, 5] NaN
如果第 1 列中的整数可以在第 2 列的整数列表中找到,我想在第 3 列中插入 1
:
col_1 col_2 col_3
0 1 [1, 2] 1
1 2 NaN NaN
2 3 [3, 5, 9] 1
3 4 [2] NaN
4 5 [8, 5] 1
我试图这样解决它:
for i in range(0,len(df)):
if df["col_1"][i] in df["col_2"][i]:
df["col_3"][i]=1
这给了我 TypeError: argument of type 'float' is not iterable
因为第 2 列中的 NaN
并且我无法找到处理的方法有了它。
(我尝试使用基于 .isin
的不同解决方案来解决此问题,但这不起作用,因为 AttributeError: 'list' 对象没有属性 'isin'
.)
然后我想到用 0
替换 col_2 中的所有 NaN
,以便我的初始 for 循环能够运行。 col_1 中没有 0
,并且永远不会,所以我可以接受该解决方案,因为这不会导致 col_3 中的错误匹配。为此,
df.loc[df["col_2"].isnull(), "col_2"] = 0
还不够,因为 if in
无法处理整数:TypeError: argument of type 'int' is not iterable
。我需要将 0
作为列表的元素插入,但不能只使用 =[0]
来代替。我尝试了基于 .at
的不同方法,因为它应该能够将列表插入到单元格中,但我无法解决。
预先感谢您的任何建议!
最佳答案
您可以使用 if-else
和 x['col_2'] == x['col_2']
过滤掉 NaN,因为 NaN != NaN
为 False
,也可将 True
的值转换为 1
,由字典使用 map
, False
值不在字典中,因此返回 NaN
s:
f = lambda x: x['col_1'] in x['col_2'] if x['col_2'] == x['col_2'] else np.nan
df['col_3'] = df.apply(f, 1).map({True:1})
print (df)
col_1 col_2 col_3
0 1 [1, 2] 1.0
1 2 NaN NaN
2 3 [3, 5, 9] 1.0
3 4 [2] NaN
4 5 [8, 5] 1.0
或者使用DataFrame.dropna
删除 NaN 行并在分配回新列后添加删除的 NaN
s:
f = lambda x: x['col_1'] in x['col_2']
df['col_3'] = df.dropna(subset=['col_1', 'col_2']).apply(f, 1).map({True:1})
print (df)
col_1 col_2 col_3
0 1 [1, 2] 1.0
1 2 NaN NaN
2 3 [3, 5, 9] 1.0
3 4 [2] NaN
4 5 [8, 5] 1.0
关于python - 检查 Python 数据框中的列表是否包含特定值,同时忽略 NaN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57936615/