Подход, который я бы выбрал, очень похож на ответ на исходную проблему.
Установите столбцы id как индекс, используйте combine_first
, как в исходном сообщении. Однако, поскольку combine_first
возвращает объединение меток обоих фреймов данных (то есть строк и столбцов), после его применения выберите только те индексы, которые принадлежат df1
idx = ['id_col1', 'id_col2']
df1 = df1.set_index(idx)
df2 = df2.set_index(idx)
result_1 = df1.combine_first(df2).loc[df1.index]
# result_1 outputs:
name age sex
id_col1 id_col2
101 1M Steve 21.0 M
3M Steve 21.0 M
102 1M Mark 25.0 M
Чтобы сгенерировать result_2
, сначала следуйте подходу, предложенному в предыдущем посте:
mask = pd.notnull(df1) & ~df1.eq(df2) & pd.notnull(df2)
result_2 = pd.concat([df1[mask], df2[mask]]).dropna(how='all')
Это генерирует желаемые данные, однако порядок немного отличается от того, что вы представляете, потому что df1[mask]
накладывается поверх df2[mask]
.
отсортируйте по индексу, чтобы получить окончательный результат:
result_2.sort_index()
# outputs
name age sex
id_col1 id_col2
101 3M NaN 21.0 NaN
3M NaN 25.0 NaN
102 1M Mark NaN NaN
1M Ria NaN NaN
Единственное отличие этого решения от решения, представленного в первом посте, - это дополнительные ...loc[df1.index]
и result_2.sort_index()