Как объединить фреймы данных с помощью условия?

#python #pandas #dataframe

#python #панды #фрейм данных

Вопрос:

Предположим, у меня есть следующий входной фрейм данных,

df1,

  col1_1 | col2 | ....
AB0123  |      |
0678    |      |
AB0567  |      | 
0921    |      |
6752    |      |
 

и следующий поисковый фрейм данных

df2,

 col1   | col2 | col3 |...
AB0123 |      |  abc |
AB0567 |      |  dfe | 
       |0678  |  ghi |
       |0921  |  jkl |
       |6752  |  mno |
 

Конечный результат df,

  col1_1 | col1_or_col2 | col2....
AB0123  |     abc      |
0678    |     ghi      |
AB0567  |     dfe      |
0921    |     jkl      |
6752    |     mno      |
 

что я имею в виду, так это создать два временных столбца в выходном df, а затем создать отдельную функцию * для генерации col1_or_col2,

* Функция проверит каждую строку и примет окончательное непустое значение между temp_col2 или temp_col3

  col1  | temp_col1 | temp_col2 | col1_or_col2
AB0123 |   abc     |           |    abc
0678   |           |     ghi   |    ghi
AB0567 |   dfe     |           |    dfe
0921   |           |     jkl   |    jkl
6752   |           |     mno   |    mno
 

Есть ли функция pandas, которую я могу использовать для эффективного решения вышеуказанной проблемы?

Комментарии:

1. Что это значит: «на основе col2 и col3 из поиска df1»?

2. почему вы меняете значения col2 на col1? не могли бы вы подробнее описать логику

3. Пожалуйста, добавьте пример «входного» фрейма данных

4. Я отредактировал вопрос и, надеюсь, он даст больше информации @Dani Mesejo

5. Я отредактировал вопрос, и, надеюсь, он даст больше информации @anky

Ответ №1:

Вы можете сделать это элегантно, включив pop в дополнение к моему комментарию. Этот код обновляет col1 второй df2 фрейм данных, заполняя NaN значения из col1 col2 значениями, одновременно используя pop для удаления ненужного теперь col2 из фрейма данных. Теперь вы объединяете это новое df2 с. df1 Убедитесь, что ваши столбцы слияния имеют тип object данных перед объединением (например df2['col1'] = df2['col1'].astype(str) , и сделайте то же самое для других столбцов или проверьте тип данных с df2.info() помощью).:

 df1.merge(df2.assign(col1=df2['col1'].fillna(df2.pop('col2'))), on='col1')

    col1    col3
0   AB0123  abc
1   O678    ghi  #Please note that when reading in the data, I change "0" to "O" as it was dropping the leading "0" and reading data as integer.  See comments.
2   AB0567  dfe
3   O921    jkl  #Please note that when reading in the data, I change "0" to "O" as it was dropping the leading "0" and reading data as integer.  See comments.
4   6752    mno
 

Это результат работы части внутри merge и то , во что вы объединяетесь df1 :

 df2.assign(col1=df2['col1'].fillna(df2.pop('col2')))

    col1    col3
0   AB0123  abc
1   AB0567  dfe
2   O678    ghi
3   O921    jkl
4   6752    mno
 

Комментарии:

1. спасибо за ваш ответ. Могу ли я узнать, что вы подразумеваете под «Пожалуйста, обратите внимание, что я меняю «0» на «O», так как он отбрасывал начальную букву «0»

2. @royalewithcheese я использую pd.read_clipboard() для чтения данных stackoverflow, и он прочитал один col2 из df2 них как целое число и отбросил ноль, что означает, что данные не были объединены правильно. Это просто связано с тем, как я переносил ваши данные StackOverflow в свой ноутбук jupyter.

3. df объединяются на основе column1 только это seems…so не получение соответствующих данных из col3 в col2, а получение данных из col3, связанных с col1

Ответ №2:

Давайте попробуем объединить df2 и df1 и отбросить col1. df2=df2.assign(col1=df2.col2.astype(str) df2.col1).drop(columns=['col2'])

Если существуют скрытые взаимосвязи, выполните следующие действия

Создайте новый df3 фрейм df2.col1 данных, объединив и df2.col3 .

 df3=df2.assign(col1=df2.col2.astype(str) df2.col1).drop(columns=['col2'])
 

Создайте диктант из df3 . Диктант будет иметь df3.col1 как ключ, df3.col3 так и значение. Нанесите это на карту, чтобы df1.col1 увидеть ниже

 df1['col2']=df1.col1.map(dict(zip(df3.col1,df3.col3)))



   col1_1 col2
0  AB0123  abc
1    O678  ghi
2  AB0567  dfe
3    O921  jkl
4    6752  mno