web-dev-qa-db-ja.com

Pandasデータフレーム列の値が列リストにあるかどうかを確認します

データフレームがあります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]

ididlistにあるかどうかを確認し、それを選択またはフラグを立てる必要があります。次のバリエーションを試しましたが、コメント付きのエラーが表示されます。

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リスト内包表記?

ここで、ididlistにある行を選択するか、ididlistにある行に1のフラグを立てる解決策を探しています。 。結果の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]

助けてくれてありがとう!

6
clg4

applyを使用します:

df['flag'] = df.apply(lambda x: int(x['id'] in x['idlist']), axis=1)
print (df)
    id                idlist  flag
0   12    [1, 5, 7, 12, 112]     1
1  112  [5, 7, 12, 111, 113]     0

同様:

df['flag'] = df.apply(lambda x: x['id'] in x['idlist'], axis=1).astype(int)
print (df)
    id                idlist  flag
0   12    [1, 5, 7, 12, 112]     1
1  112  [5, 7, 12, 111, 113]     0

list comprehension

df['flag'] = [int(x[0] in x[1]) for x in df[['id', 'idlist']].values.tolist()]
print (df)
    id                idlist  flag
0   12    [1, 5, 7, 12, 112]     1
1  112  [5, 7, 12, 111, 113]     0

フィルタリングのソリューション:

df = df[df.apply(lambda x: x['id'] in x['idlist'], axis=1)]
print (df)
   id              idlist
0  12  [1, 5, 7, 12, 112]

df = df[[x[0] in x[1] for x in df[['id', 'idlist']].values.tolist()]]
print (df)

   id              idlist
0  12  [1, 5, 7, 12, 112]
7
jezrael

df.applyを使用して各行を処理し、条件をチェックして2番目の出力要求として結果を提供する新しい列フラグを作成できます。

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

4

単純な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]
1
rnso

issubsetを使用する

df.apply(lambda  x : set([x.id]).issubset(x.idlist),1).astype(int)
Out[378]: 
0    1
1    0
dtype: int32

np.vectorizeを使用する

def myfun(x,y):
    return np.in1d(x,y)


np.vectorize(myfun)(df.id,df.idlist).astype(int)

タイミング:

%timeit np.vectorize(myfun)(df.id,df.idlist).astype(int)
10000 loops, best of 3: 92.3 µs per loop
%timeit df.apply(lambda  x : set([x.id]).issubset(x.idlist),1).astype(int)
1000 loops, best of 3: 353 µs per loop
1
YOBEN_S