我有一个数据框df
:
data = {'id':[12,112],
'idlist':[[1,5,7,12,112],[5,7,12,111,113]]
}
df=pd.DataFrame.from_dict(data)
看起来像这样:
id idlist
0 12 [1, 5, 7, 12, 112]
1 112 [5, 7, 12, 111, 113]
我需要检查并查看id
中是否有idlist
,然后选择或标记它。我尝试了以下变体并收到注释错误:
df=df.loc[df.id.isin(df.idlist),:] #TypeError: unhashable type: 'list'
df['flag']=df.where(df.idlist.isin(df.idlist),1,0) #TypeError: unhashable type: 'list'
解决方案的一些可能的其他方法是列表理解中的.apply
吗?
我正在寻找一个解决方案,要么选择id
位于idlist
的行,要么将行标记为id
位于idlist
的行。生成的df
应为:
id idlist
0 12 [1, 5, 7, 12, 112]
或:
flag id idlist
0 1 12 [1, 5, 7, 12, 112]
1 0 112 [5, 7, 12, 111, 113]
感谢您的帮助!
答案 0 :(得分:3)
您可以使用df.apply
并处理每一行并创建一个新的列标志,该标志将检查条件并将结果作为请求的第二个输出。
df['flag'] = df.loc[:, ('id', 'idlist')].apply(lambda x: 1 if x[0] in x[1] else 0, axis=1)
print(df)
其中x[0] is id
和x[1] is idlist
答案 1 :(得分:1)
尝试简单的for
循环:
flaglist = []
for i in range(len(df)):
if df.id[i] in df.idlist[i]:
flaglist.append(1)
else:
flaglist.append(0)
df["flag"] = flaglist
DF:
id idlist flag
0 12 [1, 5, 7, 12, 112] 1
1 112 [5, 7, 12, 111, 113] 0
删除行:
flaglist = []
for i in range(len(df)):
if df.id[i] not in df.idlist[i]:
flaglist.append(i)
df = df.drop(flaglist)
df:
id idlist flag
0 12 [1, 5, 7, 12, 112] 1
上面可以转换为列表理解以创建标志列:
df["flag"] = [df.id[i] in df.idlist[i] for i in range(len(df))]
print(df)
# id idlist flag
# 0 12 [1, 5, 7, 12, 112] True
# 1 112 [5, 7, 12, 111, 113] False
或
df["flag"] = [1 if df.id[i] in df.idlist[i] else 0 for i in range(len(df))]
print(df)
# id idlist flag
# 0 12 [1, 5, 7, 12, 112] 1
# 1 112 [5, 7, 12, 111, 113] 0
并选择行:
flaglist = [i for i in range(len(df)) if df.id[i] in df.idlist[i]]
print(df.iloc[flaglist])
# id idlist
# 0 12 [1, 5, 7, 12, 112]