Я пытаюсь объединить два фрейма данных. Каждый фрейм данных имеет два уровня индекса (дата, cusip). В столбцах некоторые столбцы совпадают между двумя (например, валюта, дата корректировки).
Как лучше всего объединить их по индексу, но не брать две копии валюты и даты корректировки.
Каждый фрейм данных состоит из 90 столбцов, поэтому я стараюсь не писать все вручную.
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
...
Если я сделаю:
dfNew = merge(df, df2, left_index=True, right_index=True, how='outer')
я получил
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
Спасибо! ...
Я использую
suffixes
опцию в.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)
Спасибо @ijoseph
источник
filter
ing (который довольно прост, но все же требует времени для поиска / запоминания с возможностью ошибок). iedfNew.drop(list(dfNew.filter(regex='_y$')), axis=1, inplace=True)
Я новичок в Pandas, но я хотел добиться того же, автоматически избегая имен столбцов с _x или _y и удаляя повторяющиеся данные. Я , наконец , сделал это, используя этот ответ , и этот один из Stackoverflow
sales.csv
доход.csv
merge.py импорт панд
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=';')
При выполнении команды слияния я заменяю
_x
суффикс пустой строкой и могу удалить столбцы, заканчивающиеся на_y
output.csv
источник
Основываясь на ответе @rprog, вы можете объединить различные части шага суффикса и фильтра в одну строку, используя отрицательное регулярное выражение:
dfNew = df.merge(df2, left_index=True, right_index=True, how='outer', suffixes=('', '_DROP')).filter(regex='^(?!.*_DROP)')
Или используя
df.join
:dfNew = df.join(df2),lsuffix="DROP").filter(regex="^(?!.*DROP)")
Регулярное выражение здесь сохраняет все, что не заканчивается словом «DROP», поэтому просто убедитесь, что вы используете суффикс, который еще не появляется среди столбцов.
источник