[python] Pandas Left Outer Join 결과 테이블이 왼쪽 테이블보다 큽니다.
왼쪽 외부 조인에 대해 이해 한 바에 따르면 결과 테이블에는 왼쪽 테이블보다 많은 행이 있어서는 안됩니다 … 이것이 잘못된 경우 알려주세요 …
내 왼쪽 테이블은 192572 행과 8 열입니다.
내 오른쪽 테이블은 42160 행과 5 열입니다.
내 왼쪽 테이블에는 ‘키’라는 오른쪽 테이블의 열과 일치하는 ‘id’라는 필드가 있습니다.
따라서 다음과 같이 병합합니다.
combined = pd.merge(a,b,how='left',left_on='id',right_on='key')
그러나 결합 된 모양은 236569입니다.
내가 무엇을 오해하고 있습니까?
답변
키가 다른 DataFrame에서 두 개 이상의 행과 일치하면이 값이 증가 할 것으로 예상 할 수 있습니다.
In [11]: df = pd.DataFrame([[1, 3], [2, 4]], columns=['A', 'B'])
In [12]: df2 = pd.DataFrame([[1, 5], [1, 6]], columns=['A', 'C'])
In [13]: df.merge(df2, how='left') # merges on columns A
Out[13]:
A B C
0 1 3 5
1 1 3 6
2 2 4 NaN
이 동작을 방지하려면 df2 에서 중복 을 삭제하십시오.
In [21]: df2.drop_duplicates(subset=['A']) # you can use take_last=True
Out[21]:
A C
0 1 5
In [22]: df.merge(df2.drop_duplicates(subset=['A']), how='left')
Out[22]:
A B C
0 1 3 5
1 2 4 NaN
답변
예를 들어 모든 열이 복제되지 않은 경우 복제 된 데이터 손실을 포함하지 않는이 동작을 방지하기 위해 사용할 수있는 전략도 있습니다. 당신이 가지고 있다면
In [1]: df = pd.DataFrame([[1, 3], [2, 4]], columns=['A', 'B'])
In [2]: df2 = pd.DataFrame([[1, 5], [1, 6]], columns=['A', 'C'])
한 가지 방법은 중복의 평균을 취하는 것입니다 (합계 등을 취할 수도 있음).
In [3]: df3 = df2.groupby('A').mean().reset_index()
In [4]: df3
Out[4]:
C
A
1 5.5
In [5]: merged = pd.merge(df,df3,on=['A'], how='outer')
In [6]: merged
Out[204]:
A B C
0 1 3 5.5
1 2 4 NaN
또는 pd.to_numeric ()을 사용하여 변환 할 수없는 숫자가 아닌 데이터가 있거나 단순히 평균을 취하지 않으려는 경우 중복을 열거하여 병합 변수를 변경할 수 있습니다. 그러나이 전략은 중복이 두 데이터 세트에 모두 존재하는 경우에 적용됩니다 (동일한 문제 동작을 유발하고 공통 문제이기도 함).
In [7]: df = pd.DataFrame([['a', 3], ['b', 4],['b',0]], columns=['A', 'B'])
In [8]: df2 = pd.DataFrame([['a', 3], ['b', 8],['b',5]], columns=['A', 'C'])
In [9]: df['count'] = df.groupby('A')['B'].cumcount()
In [10]: df['A'] = np.where(df['count']>0,df['A']+df['count'].astype(str),df['A'].astype(str))
In[11]: df
Out[11]:
A B count
0 a 3 0
1 b 4 0
2 b1 0 1
df2에 대해 동일한 작업을 수행하고 df 및 df2에 개수 변수를 삭제하고 ‘A’에 병합합니다.
In [16]: merged
Out[16]:
A B C
0 a 3 3
1 b 4 8
2 b1 0 5
몇 가지 메모. 이 마지막 경우에는 .duplicated 대신 .cumcount ()를 사용합니다. 주어진 관찰에 대해 둘 이상의 중복이있는 경우 일 수 있기 때문입니다. 또한 np.where () 명령을 사용하기 때문에 .astype (str)을 사용하여 개수 값을 문자열로 변환하지만 pd.concat () 또는 다른 것을 사용하면 다른 응용 프로그램을 허용 할 수 있습니다.
마지막으로 하나의 데이터 세트에만 중복이 있지만 계속 유지하려는 경우 후자 전략의 전반부를 사용하여 결과 병합에서 중복을 구별 할 수 있습니다.
답변
주어진 답변에 대한 작은 추가 사항은 오른쪽 테이블에 일치하는 중복 ID가있는 경우 오류를 발생시키는 데 사용할 수있는 validate라는 매개 변수가 있다는 것입니다.
combined = pd.merge(a,b,how='left',left_on='id',right_on='key', validate = 'm:1')