针对另一列检查数据帧中多个列的高效方法

时间:2020-08-12 13:41:47

标签: python pandas

因此给出一个字符串df:

   id   v0    v1    v2     v3     v4
0   1  '10'   '5'  '10'   '22'   '50'   
1   2  '22'  '23'  '55'   '60'   '50'   
2   3   '8'   '2'  '40'   '80'  '110'  
3   4  '15'  '15'  '25'  '100'  '101'

我需要检查v0:4列中的值是否在单独的第二个数据帧的ID列中:

     ID   State 
0   '10'   'TX'
1   '40'   'VT'
2   '3'    'FL'
3   '15'   'CA'

如果是,我想返回存在的值作为新列:

    v0    v1    v2     v3     v4      matches
0  '10'   '5'  '10'   '22'   '50'   ['10','10']
1  '22'  '23'  '55'   '60'   '50'   ['']
2   '8'   '2'  '40'   '80'  '110'   ['40']
3  '15'  '15'  '25'  '100'  '101'   ['15','15']

我打算在该df上使用df.explode,然后将其加入第二个数据帧。

目前,我正在这样做:

def match_finder(some_list):
    good_list = []
    for x in some_list:
        if second_df['ID'].str.contains(x).any():
            good_list.append(x)
            continue
        else:
            pass
    return good_list

df['matches'] = [
    match_finder([df.iloc[x]["v0"], df.iloc[x]["v1"], df.iloc[x]["v2"], df.iloc[x]["v3"], df.iloc[x]["v4"]])
    for x in range(len(df))]

这不会引发错误,但是非常慢。

2 个答案:

答案 0 :(得分:2)

您可以使用whereisin立即选择second_df ID中df v0:4中的所有值,然后使用stack删除nangroupby级别= 0,它是df的原始索引,agglist。要像第二行一样添加缺失值,可以将reindex与df的原始索引一起使用。

df['matches'] = (df.filter(regex='v\d')
                   .where(lambda x: x.isin(second_df['ID'].to_numpy()))
                   .stack()
                   .groupby(level=0).agg(list)
                   .reindex(df.index, fill_value=[])
                )
print(df)
   id    v0    v1    v2     v3     v4       matches
0   1  '10'   '5'  '10'   '22'   '50'  ['10', '10']
1   2  '22'  '23'  '55'   '60'   '50'            []
2   3   '8'   '2'  '40'   '80'  '110'        ['40']
3   4  '15'  '15'  '25'  '100'  '101'  ['15', '15']

答案 1 :(得分:0)

确定潜在的匹配之后,您可以使用df.agg在轴1上使用聚合,并使用pd.Series.notna过滤NaN。

v = df.loc[:,'v0':'v4']
m = v.isin(s['ID'].to_numpy()) # s is second datafrane
df['match'] = v[m].agg(lambda x: x[x.notna()].tolist(),axis=1)

   id    v0    v1    v2     v3     v4       matches
0   1  '10'   '5'  '10'   '22'   '50'  ['10', '10']
1   2  '22'  '23'  '55'   '60'   '50'            []
2   3   '8'   '2'  '40'   '80'  '110'        ['40']
3   4  '15'  '15'  '25'  '100'  '101'  ['15', '15']
相关问题