Как «спарить» строки и объединить их в одну при объединении двух pandas фреймов данных? - PullRequest
0 голосов
/ 02 марта 2020

Заранее извиняюсь за то, что, вероятно, будет объединение предыдущих вопросов / тем. Я потратил много времени на различные связанные статьи и считаю, что теряюсь в лучшем подходе к использованию. Проблема:

У меня есть два Pandas DataFrames одинакового размера, имена столбцов и индексы. Они оба получены из отдельных SQL поисков. У меня есть третий DataFrame, который служит диктом, так что я могу использовать операции объединения / слияния для заполнения пустых столбцов в каждом из двух исходных DataFrames. Как только это будет завершено, и столбцы в обоих DataFrames заполнены, я хотел бы объединить их так, чтобы соответствующие записи по двум объединялись в одну строку в одном объединенном DataFrame вместо строки в каждом DataFrame. Очевидно, будет название столбца cla sh, что является частью проблемы. Вот представление:

    frame1
Out[87]: 
   matchupid   primary    geo
0      27812  student1   east
1      91876  student3   east
2      65019  student5   west
3      21632  student7  south
frame2
Out[88]: 
   matchupid   primary      geo
0      27812  student2     west
1      91876  student4  central
2      65019  student6    north
3      21632  student8     east

Если не указывать элемент управления для экономии места в записи, вот что я получаю при объединении каждого фрейма со фреймом словаря. Результаты здесь верны (для меня) до сих пор:

a1 = frame1.merge(dictFrame, on="primary")
a1
Out[70]: 
   matchupid   primary    geo  matchup q1_res q2_res
0      27812  student1   east    27812   fail   41.2
1      91876  student3   east    91876   78.2   pass
2      65019  student5   west    65019  defer    107
3      21632  student7  south    21632  210.4   fail
a2 = frame2.merge(dictFrame, on="primary")
a2
Out[72]: 
   matchupid   primary      geo  matchup q1_res q2_res
0      27812  student2     west    27812  defer   fail
1      91876  student4  central    91876  104.2  defer
2      65019  student6    north    65019   92.2   91.4
3      21632  student8     east    21632   pass   pass
a3 = pd.concat([a1, a2])
a3
Out[75]: 
   matchupid   primary      geo  matchup q1_res q2_res
0      27812  student1     east    27812   fail   41.2
1      91876  student3     east    91876   78.2   pass
2      65019  student5     west    65019  defer    107
3      21632  student7    south    21632  210.4   fail
0      27812  student2     west    27812  defer   fail
1      91876  student4  central    91876  104.2  defer
2      65019  student6    north    65019   92.2   91.4
3      21632  student8     east    21632   pass   pass

Теперь желаемое состояние будет выглядеть примерно так (немного надуманным, поскольку я не могу понять, как сделай это :)). ЭТО НЕ ОСУЩЕСТВЛЯЕТСЯ - ЭТО ЖЕЛАЕТ РЕЗУЛЬТАТ:

Out[97]: 
   matchupid   primary q1_res q2_res secondary secondary_q1res secondary_q2res
0      27812  student1   fail   41.2      student2        defer         fail
1      91876  student3   78.2   pass      student4        104.2         defer
2      65019  student5  defer    107      student6        92.2          91.4
3      21632  student7  210.4   fail      student8        pass          pass

Я пробовал несколько разных подходов, и мне любопытно, является ли тот факт, что как индексы, так и совпадающие IP являются То же самое дает некоторое преимущество. Я подумал, что, возможно, использование groupby на matchupid позволит мне работать в тех парах, которые мне нужны. Остальные задачи, если это сработало, состояли бы в том, чтобы 1 / превратить две строки в одну, 2 / добавить их в новый (?) DataFrame и 3 / изменить имена столбцов. Кто-нибудь возражает предложить подход или мою недостающую ссылку? Заранее спасибо!

grouped = a3.groupby('matchupid')
grouped.get_group(21632)
Out[109]: 
   matchupid   primary q1_res q2_res
3      21632  student7  210.4   fail
3      21632  student8   pass   pass

1 Ответ

0 голосов
/ 03 марта 2020

Похоже, что это работа для pd.concat(axis=1), "горизонтальная" конкатенация:

# Create a temporary DataFrame from a2 with correct column names
temp = a2.rename(columns={'primary': 'secondary', 
                          'q1_res':'secondary_q1res',
                          'q2_res':'secondary_q2res'})
temp = temp.drop(columns=['matchup', 'geo'])

# Horizontally concat with relevant columns of a1
a3 = pd.concat([a1.drop(columns=['matchup', 'geo']), temp], axis=1)
...