熊猫:从包含列表的另一个df列中搜索一个df的列值

时间:2020-08-24 20:40:02

标签: python-3.x pandas list dataframe

我需要将df1 ['numsearch']列中的值搜索到df2 ['Numbers']中的列表中。如果数字在那些列表中,那么我想将df2 ['Score']列中的值添加到df1。请参阅下面的期望输出。

df1 = pd.DataFrame(
    {'Day':['M','Tu','W','Th','Fr','Sa','Su'],
     'numsearch':['1','20','14','99','19','6','101']
    })

df2 = pd.DataFrame(
    {'Letters':['a','b','c','d'],
     'Numbers':[['1','2','3','4'],['5','6','7','8'],['10','20','30','40'],['11','12','13','14']],
     'Score': ['1.1','2.2','3.3','4.4']})


desired output
  Day  numsearch            Score
0   M          1             1.1
1  Tu         20             3.3
2   W          4             4.4
3  Th         99          "No score"
4  Fr         19          "No score"
5  Sa          6             2.2 
6  Su        101          "No score"

我已经编写了一个用于测试数据的for循环。

scores = []
for s,ns in enumerate(ppr_data['SN']):
    match = ''
    for k,q in enumerate(jcr_data['All_ISSNs']):    
        if ns in q:
            scores.append(jcr_data['Journal Impact Factor'][k])
            match = 1
        else:
            continue
    if match == "":
        scores.append('No score')
        match = ""
df1['Score'] = np.array(scores)

在我的小型测试中,但是上面的代码有效,但是当处理较大的数据文件时,它会创建重复项。因此,这显然不是执行此操作的最佳方法。

我确定还有更多适合熊猫的代码行以.fillna("No score")结尾。

我尝试使用loc语句,但是我迷上了在包含列表的列中搜索一个数据框的值的方法。

谁能阐明一些想法?

2 个答案:

答案 0 :(得分:3)

df2=df2.explode('Numbers')#Explode df2 on Numbers
d=dict(zip(df2.Numbers, df2.Score))#dict Numbers and Scores
df1['Score']=df1.numsearch.map(d).fillna('No Score')#Map dict to df1 filling NaN with No Score

可以将其缩短如下:

df2=df2.explode('Numbers')#Explode df2 on Numbers
df1['Score']=df1.numsearch.map(dict(zip(df2.Numbers, df2.Score))).fillna('No Score')



   Day numsearch     Score
0   M         1       1.1
1  Tu        20       3.3
2   W        14       4.4
3  Th        99  No Score
4  Fr        19  No Score
5  Sa         6       2.2
6  Su       101  No Score

答案 1 :(得分:2)

您可以尝试左联接和fillna:

df1.merge(df2.explode('Numbers'), 
          left_on='numsearch', 
          right_on='Numbers', how='left')[['Day', 'numsearch', 'Score']].fillna("No score")

输出:

  Day numsearch     Score
0   M         1       1.1
1  Tu        20       3.3
2   W        14       4.4
3  Th        99  No score
4  Fr        19  No score
5  Sa         6       2.2
6  Su       101  No score