#python-3.x #pandas #list #dataframe
#python-3.x #pandas #Список #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)
В моем небольшом тесте приведенный выше код работает, но при работе с файлами данных большего размера создаются дубликаты. Итак, это явно не лучший способ сделать это.
Я уверен, что есть более подходящая для pandas строка кода, которая заканчивается на .fillna("No score")
.
Я пытался использовать loc
инструкцию, но я зациклился на поиске значений одного фрейма данных в столбце, который содержит списки.
Кто-нибудь может пролить некоторый свет?
Ответ №1:
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:
Вы можете попробовать левое соединение и заполнить:
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
Комментарии:
1. Спасибо за этот ответ. Работает как шарм.