[python] Pandas Merge-열 중복을 방지하는 방법

두 데이터 프레임 간의 병합을 시도하고 있습니다. 각 데이터 프레임에는 두 가지 인덱스 수준 (날짜, 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

감사합니다! …



답변

하나의 DataFrame에만있는 열을 해결하고이를 사용하여 병합에서 열의 하위 집합을 선택할 수 있습니다.

cols_to_use = df2.columns.difference(df.columns)

그런 다음 병합을 수행합니다 (이것은 인덱스 개체이지만 편리한 tolist()방법 이 있음에 유의하십시오 ).

dfNew = merge(df, df2[cols_to_use], left_index=True, right_index=True, how='outer')

이렇게하면 병합시 열이 충돌하는 것을 방지 할 수 있습니다.


답변

다음에서 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


답변

저는 Pandas를 처음 접했지만 _x 또는 _y가있는 열 이름을 자동으로 피하고 중복 데이터를 제거하여 동일한 결과를 얻고 싶었습니다. 드디어이 사용하여 한 대답하나의 유래에서을

sales.csv

    도시; 주; 단위
    멘 도시 노; CA; 1
    덴버; CO; 4
    오스틴; TX; 2

수익 .csv

    branch_id; city; revenue; state_id
    10; 오스틴; 100; TX
    20; 오스틴; 83; TX
    30; 오스틴; 4; TX
    47; 오스틴; 200; TX
    20; 덴버; 83; CO
    30; 스프링 필드; 4; I

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

    id; 도시; 주; 단위; branch_id; 수익; state_id
    0; 덴버; CO; 4; 20; 83; CO
    1; 오스틴; TX; 2; 10; 100; TX
    2; 오스틴; TX; 2; 20; 83; TX
    3; 오스틴; TX; 2; 30; 4; TX
    4; 오스틴; TX; 2; 47; 200; TX


답변

@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”이라는 단어로 끝나지 않는 모든 항목을 유지 하므로 이미 열 사이에 나타나지 않는 접미사를 사용하십시오.


답변