Панды: Как объединить кадры данных по связанным столбцам без точных совпадений и возможных внутренних дубликатов?

1

Этот вопрос связан с Pandas, но не совсем так : как объединить два фрейма данных путем сопоставления ближайшего индекса? ,

Учитывая два df1[['A1', 'B1']] и df2[['A2', 'B2']], я хотел бы объединить их, чтобы я в итоге получил df3[['A2, 'B2', 'B1', 'A1']] где все значения 'A1' были сопоставлены ближайшим 'B2' с 'B1'. Ниже приведен пример, и в конце вы найдете полный образец данных и воспроизводимый код.

df1: (дубликат B1 = -9.33)

       A1     B1
0 -128.65 -12.30
1 -117.74 -11.98
2 -117.19 -11.91
3 -109.43 -10.03
4  -93.75  -9.33
5  -87.27  -9.33
6  -85.59  -5.96
7  -76.18  -5.51

df2:

       A2     B2
0  -69.06 -12.64
1  -86.88 -12.12
2  -95.95 -11.35
3 -103.87 -10.67
4 -105.78  -9.63
5 -108.11  -9.20
6 -111.07  -9.06
7 -126.42  -6.37

Обратите внимание, что df2 ['A2'] идет вниз, а все остальные столбцы - восходящие.

Желаемый вывод:

       A2     B2     B1   A1
0  -69.06 -12.64 -12.30 -128.65  
1  -86.88 -12.12 -11.98 -117.74  
2  -95.95 -11.35 -10.03 -109.43
3 -103.87 -10.67 -10.03 -109.43 
4 -105.78  -9.63  -9.33 -87.27  
5 -108.11  -9.20  -9.33 -87.27
6 -111.07  -9.06  -5.96 -85.59
7 -126.42  -6.37  -5.96 -85.59

Предостережения:

Правильным соответствием для df2['B2']=-12.12 является df1['B1']=-11.98 с соответствующим df['A1']=-117.74, поскольку df2['B2']=-12.12 больше, чем df2['B2']=-12.30 а -11.98 - следующий шаг в столбце.

Для повторяющихся значений df1['B1'].iloc[4] = df1['B1'].iloc[5] = -9.33, df1['A1'] = -87.27 - правильное совпадение, поскольку это величайшая ценность.

Если лучшее решение включает установку некоторых столбцов в качестве индекса, я не буду возражать!

Вот воспроизводимый фрагмент:

#imports
import numpy as np
import pandas as pd

# Some sample data
np.random.seed(1234)

data1 = {'A1':sorted(np.random.normal(100, 20, 8)*-1),
         'B1':sorted(np.random.normal(10, 2, 8)*-1)}


data2 = {'A2':sorted(np.random.normal(100, 20, 8)*-1,reverse = True),
         'B2':sorted(np.random.normal(10, 2, 8)*-1)}

# Two dataframes
df1 = pd.DataFrame(data1).round(2)
df2 = pd.DataFrame(data2).round(2)

# Duplicate scenario 1: Duplicate A1 values
df1['B1'].iloc[4] = df1['B1'].iloc[5]

Спасибо за любые предложения!

  • 0
    следует 5 -108.11 -9.20 объединить 5 -108.11 -9.20 с 6 -85.59 -5.96 ?
Теги:
pandas

1 ответ

1
Лучший ответ

Это pd.merge_asof после первой обработки дубликатов. Сортируйте по 'A1' затем отбрасывайте дубликаты по 'B1', оставляя наибольшее значение 'A1' для каждого уникального 'B1':

import pandas as pd
#df2 = df2.sort_values('B2') # If not sorted by 'B2'

pd.merge_asof(df2, 
              df1.sort_values('A1').drop_duplicates('B1', keep='last').sort_values('B1'),
              left_on='B2', right_on='B1', direction='forward')

Выход:

       A2     B2      A1     B1
0  -69.06 -12.64 -128.65 -12.30
1  -86.88 -12.12 -117.74 -11.98
2  -95.95 -11.35 -109.43 -10.03
3 -103.87 -10.67 -109.43 -10.03
4 -105.78  -9.63  -87.27  -9.33
5 -108.11  -9.20  -85.59  -5.96
6 -111.07  -9.06  -85.59  -5.96
7 -126.42  -6.37  -85.59  -5.96

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню