Объединение двух фреймов данных на основе условия в третьем столбце - PullRequest
0 голосов
/ 05 августа 2020



Я хочу объединить два фрейма данных (df1 и df2) на основе столбца PERMNO соотв. LPERMNO:
df1.merge(df2, left_on='PERMNO', right_on='LPERMNO')

Однако при слиянии мне также нужно учитывать, что столбец date из df1 находится между диапазоном двух столбцов LINKDT и LINKENDDT из df2, поскольку df2 содержит различную информацию для каждой строки (см. столбец PRC из df2).

Например, индекс [0,1] из df1 должен объединиться с индексом 0 из df2
и индекс [2,3] из df1 должны объединиться с индексом 2 из df2, поскольку значение date находится в двух столбцах LINKDT и LINKENDDT.

К сожалению, я немного потерялся здесь, поэтому любая помощь приветствуется!

df1

    PERMNO  date
0   66325   2006-03-30
1   66325   2006-06-30
2   66325   2015-09-30
3   66325   2015-12-30

df2:

    LPERMNO LINKDT      LINKENDDT   PRC
0   66325   1992-07-01  2014-04-30  10
1   66325   1983-09-23  1992-06-30  12
2   66325   2014-05-01  2019-12-31  8.5

ОБНОВЛЕНИЕ :

ожидаемый результат

Выходной фрейм данных имеет форму 2'000 '000x180.

    PERMNO  date        LPERMNO   LINKDT      LINKENDDT    PRC   
0   66325   2006-03-30  66325     1992-07-01  2014-04-30   10
1   66325   2006-06-30  66325     1992-07-01  2014-04-30   10
2   66325   2015-09-30  66325     2014-05-01  2019-12-31   8.5
3   66325   2015-12-30  66325     2014-05-01  2019-12-31   8.5

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Попробуйте:

df_merged = df1.merge(df2, left_on=['PERMNO'], right_on=['LPERMNO'])

# if ['date', 'LINKDT', 'LINKENDDT'] already are in datetime format, ignore this three lines
df_merged['date'] = pd.to_datetime(df_merged['date'])
df_merged['LINKDT'] = pd.to_datetime(df_merged['LINKDT'])
df_merged['LINKENDDT'] = pd.to_datetime(df_merged['LINKENDDT'])

# Assuming LINKDT < LINKENDDT
df_merged = df_merged[(df_merged['date'] >= df_merged['LINKDT']) & (df_merged['date'] <= df_merged['LINKENDDT'])]

Вывод:

    PERMNO       date  LPERMNO     LINKDT  LINKENDDT   PRC
0    66325 2006-03-30    66325 1992-07-01 2014-04-30  10.0
3    66325 2006-06-30    66325 1992-07-01 2014-04-30  10.0
8    66325 2015-09-30    66325 2014-05-01 2019-12-31   8.5
11   66325 2015-12-30    66325 2014-05-01 2019-12-31   8.5
0 голосов
/ 05 августа 2020

Я не знаю, есть ли более простой / быстрый / лучший способ сделать это, но это то, что я вам предлагаю. Слияние, которое вы пытаетесь получить, кажется слишком сложным для .merge (), вместо этого пытались использовать условия для столбцов.

permno = []
date = []
linkdt = []
linkenddt = []
prc = []
for i in range(0, df1.shape[0]):
    for j in range(0, df2.shape[0]):
        if (df1['PERMNO'][i]==df2['LPERMNO'][j]) & (df1['date'][i] > df2['LINKDT'][j]) & (df1['date'][i] < df2['LINKENDDT'][j]):
            permno.append(df1['PERMNO'][i])
            date.append(df1['date'][i])
            linkdt.append(df2['LINKDT'][j])
            linkenddt.append(df2['LINKENDDT'][j])
            prc.append(df2['PRC'][j])

merged = pd.DataFrame(list(zip(permno, linkdt, date, linkenddt, prc)), 
                       columns = ['PERMNO', 'LINKDT', 'LINKENDDT', 'PRC'])
      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...