Лучший способ реализовать команду SQL "MERGE INTO" с python - pandas? - PullRequest
1 голос
/ 14 марта 2020

Я хочу сделать условный переход с 2 pandas фреймами данных - аналогично слиянию с SQL функцией. Для каждой строки в исходном фрейме данных, если индекс не существует, вставьте его в целевой фрейм данных. Если индекс существует, проверьте вторичные условия. Если условия выполнены, обновите существующую строку.

Вот пример:

import pandas as pd
df1 = pd.DataFrame([{'index':'1st','checkval':2,'storeval':'elephant'},
                    {'index':'2nd','checkval':7,'storeval':'giraffe'}]).set_index('index')

df2 = pd.DataFrame([{'index':'1st','checkval':3,'storeval':'hippopotamus'},
                    {'index':'3rd','checkval':4,'storeval':'seagull'}]).set_index('index')

Вот как выглядит df1

        checkval    storeval
index       
1st     2           elephant
2nd     7           giraffe

Вот как выглядит df2 как

     checkval   storeval
index       
1st     3       hippopotamus
3rd     4       seagull

Вот грубая сила, способ сделать то, что я описываю:

for ind2, row2 in df2.iterrows():
    found = False
     for ind1, row1 in df1.iterrows():
        if ind2 == ind1:
            #Index matched
            found = True
            if row2['checkval'] > row1['checkval']:
                #Conditions met, updating existing row
                df1.loc[ind1] = row2
    if not found:
        # Row not already in df, insert
        df1 = df1.append(row2)

Вывод:

    checkval    storeval
index       
1st     3   hippopotamus
2nd     7   giraffe
3rd     4   seagull

Однако я бы с удовольствием найдите какую-нибудь встроенную функцию, например

df1.merge(d2, how = 'left', conditions = lambda df1,df2: df2['checkval']>df1['checkval'])

или что-то в этом роде. У кого-нибудь есть предложения по улучшению метода «грубой силы»?

1 Ответ

1 голос
/ 14 марта 2020

старайтесь не создавать ненужных циклов в pandas, это замедляется и портит код

Я думаю, мы можем использовать DataFrame.append с groupby.last сортировка ранее:

new_df = df1.append(df2).sort_values('checkval').groupby(level=0).last()
#new_df = df1.append(df2).sort_values('checkval').groupby(level='index').last()

Варианты:

new_df = df1.append(df2)
new_df = new_df.loc[~new_df.sort_values('checkval')
                           .index
                           .duplicated(keep='last'),:].sort_index()
print(new_df)

new_df = (df1.append(df2)
             .reset_index()
             .sort_values('checkval')
             .drop_duplicates(subset='index',keep='last')
             .set_index('index')
             .sort_index())
print(new_df)

Вывод

       checkval      storeval
index                        
1st           3  hippopotamus
2nd           7       giraffe
3rd           4       seagull
...