Pandas Dataframe检查列值是否在列列表中

时间:2017-11-27 14:34:17

标签: python pandas where list-comprehension apply

我有一个数据框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]

感谢您的帮助!

2 个答案:

答案 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 idx[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]