Próbuję połączyć dwie ramki danych. Każda ramka danych ma dwa poziomy indeksu (data, cusip). Na przykład niektóre kolumny w kolumnach pasują do tych dwóch (waluta, data dostosowania).
Jaki jest najlepszy sposób na scalenie ich według indeksu, ale nie należy brać dwóch kopii waluty i daty dostosowania.
Każda ramka danych ma 90 kolumn, więc staram się unikać pisania wszystkiego ręcznie.
df: currency adj_date data_col1 ...
date cusip
2012-01-01 XSDP USD 2012-01-03 0.45
...
df2: currency adj_date data_col2 ...
date cusip
2012-01-01 XSDP USD 2012-01-03 0.45
...
Jeśli zrobię:
dfNew = merge(df, df2, left_index=True, right_index=True, how='outer')
dostaję
dfNew: currency_x adj_date_x data_col2 ... currency_y adj_date_y
date cusip
2012-01-01 XSDP USD 2012-01-03 0.45 USD 2012-01-03
Dziękuję Ci! ...
Korzystam z
suffixes
opcji w.merge()
:dfNew = df.merge(df2, left_index=True, right_index=True, how='outer', suffixes=('', '_y')) dfNew.drop(dfNew.filter(regex='_y$').columns.tolist(),axis=1, inplace=True)
Dzięki @ijoseph
źródło
filter
ingerencji (co jest dość proste, ale wciąż czasochłonne, aby wyszukać / zapamiętać błędy). tj.dfNew.drop(list(dfNew.filter(regex='_y$')), axis=1, inplace=True)
Jestem nowy w Pandach, ale chciałem osiągnąć to samo, automatycznie unikając nazw kolumn z _x lub _y i usuwając zduplikowane dane. I wreszcie zrobił to za pomocą tej odpowiedzi i ten jeden z Stackoverflow
sales.csv
przychody.csv
merge.py importuj pandy
def drop_y(df): # list comprehension of the cols that end with '_y' to_drop = [x for x in df if x.endswith('_y')] df.drop(to_drop, axis=1, inplace=True) sales = pandas.read_csv('data/sales.csv', delimiter=';') revenue = pandas.read_csv('data/revenue.csv', delimiter=';') result = pandas.merge(sales, revenue, how='inner', left_on=['state'], right_on=['state_id'], suffixes=('', '_y')) drop_y(result) result.to_csv('results/output.csv', index=True, index_label='id', sep=';')
Wykonując polecenie merge, zastępuję
_x
sufiks pustym ciągiem i mogę usunąć kolumny kończące się na_y
output.csv
źródło
Opierając się na odpowiedzi @ rprog, możesz połączyć różne fragmenty kroku sufiksu i filtra w jedną linię za pomocą negatywnego wyrażenia regularnego:
dfNew = df.merge(df2, left_index=True, right_index=True, how='outer', suffixes=('', '_DROP')).filter(regex='^(?!.*_DROP)')
Lub za pomocą
df.join
:dfNew = df.join(df2),lsuffix="DROP").filter(regex="^(?!.*DROP)")
Wyrażenie regularne tutaj zachowuje wszystko, co nie kończy się słowem „DROP”, więc po prostu upewnij się, że używasz sufiksu, który nie pojawia się jeszcze wśród kolumn.
źródło