Объединить два кадра данных 1:1

Я хотел бы объединить два DataFram, содержащих два общих столбца. У них одинаковое количество строк, и я знаю, что порядок в обоих столбцах одинаков, поэтому они уже выровнены. Моя проблема в том, что после их слияния у меня осталось больше строк, чем было изначально.

Есть ли способ объединить эти два кадра данных и сохранить исходное число строк?

df1 = pd.DataFrame(
   [
      {"col1": 1, "col2": 1, "unique_df1_val": "value1"},
      {"col1": 2, "col2": 2, "unique_df1_val": "value2"},
      {"col1": 2, "col2": 2, "unique_df1_val": "value3"},
   ]
)

df2 = pd.DataFrame(
   [
      {"col1": 1, "col2": 1, "unique_df2_val": "value4"},
      {"col1": 2, "col2": 2, "unique_df2_val": "value5"},
      {"col1": 2, "col2": 2, "unique_df2_val": "value6"},
   ]
)


### Do some merge of the two ###


# Expected DataFrame

    col1    col2    unique_df1_val  unique_df2_val
0   1       1       value1          value4
1   2       2       value2          value5
2   2       2       value3          value6

Я пытался использовать df1.merge(df2, how="outer"), но это не дает мне правильного результата.

df1.merge(df2, how = "outer")
# Returns

    col1    col2    unique_df1_val  unique_df2_val
0   1       1       value1          value4
1   2       2       value2          value5
2   2       2       value2          value6
3   2       2       value3          value5
4   2       2       value3          value6

Если вы внимательно посмотрите, col1 не имеет 3 в качестве третьего значения, вместо этого 2. Либо ваши входные данные неверны, либо то, чего вы пытаетесь достичь, невозможно (как при создании 3)

Celius Stingher 10.11.2022 12:14

Это была опечатка, спасибо, что заметили!

Martin Lange 10.11.2022 12:17

Имеет ли значение порядок? Если вы переместите строку 2 из df2 в последнюю позицию, должен ли вывод быть таким же или значение3 должно идти со значением4?

mozway 10.11.2022 12:30

Они сортируются и выравниваются так, чтобы строки 1 в df1 и df2 были соединены и так далее для каждой строки.

Martin Lange 10.11.2022 12:33

Тогда используйте df1['unique_df2_val'] = df2['unique_df2_val'] ;)

jezrael 10.11.2022 12:33
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
59
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Используйте pd.concat вместо merge. Если ваши данные выровнены, вы можете просто объединить столбец/столбцы, которые вы хотите, в финале кадра данных.

pd.concat([df1, df2['unique_df2_val']], axis=1)

Вывод:

    col1    col2    unique_df1_val  unique_df2_val
0   1         1        value1          value4
1   2         2        value2          value5
2   2         2        value3          value6
Ответ принят как подходящий

Если все они имеют одинаковую длину и предварительно отсортированы с одинаковым количеством наблюдений на столбец 1 и столбец 2, рассмотрите возможность использования соединения вместо слияния. Однако будьте осторожны, так как операция выполняется с индексами (по умолчанию), а не со значениями столбцов:

Соедините столбцы с другим DataFrame либо по индексу, либо по ключевому столбцу. Эффективно объединяйте несколько объектов DataFrame по индексу одновременно, передавая список.

df1.join(df2,lsuffix='drop').drop(columns=[x+'drop' for x in df1.columns if x in df2.columns])

Вывод:

  unique_df1_val  col1  col2 unique_df2_val
0         value1     1     1         value4
1         value2     2     2         value5
2         value3     2     2         value6

Если операция слияния не нужна, потому что данные всегда будут идеально выровнены, то просто рассмотрите возможность определения нового столбца:

df1['unique_df2_val'] = df2['unique_df2_val']

На самом деле это не merge, это предполагает, что строки уже выровнены (в этом случае было бы лучше простое объединение или присваивание)

mozway 10.11.2022 12:28

Последний вариант тоже сработал, со второй попытки :D

Martin Lange 10.11.2022 12:40

Для эффективного решения и настоящего слияния выполните дедупликацию перед слиянием:

cols = ['col1', 'col2']

out = (df1.merge(df2, left_on=[df1.groupby(cols).cumcount(), *cols],
                     right_on=[df1.groupby(cols).cumcount(), *cols])
          .drop(columns='key_0')
      )

Вывод:

   col1  col2 unique_df1_val unique_df2_val
0     1     1         value1         value4
1     2     2         value2         value5
2     2     2         value3         value6

Ударь меня. Дополнительное пояснение: здесь дедуплицируется каждая комбинация столбцов col1 и col2 путем введения третьего столбца, в котором ведется подсчет этих дубликатов.

timgeb 10.11.2022 12:38

Другие вопросы по теме