[python] Python Pandas-두 데이터 프레임의 차이점 찾기

두 개의 데이터 프레임 df1과 df2가 있는데, 여기서 df2는 df1의 하위 집합입니다. 두 데이터 프레임의 차이 인 새 데이터 프레임 (df3)을 어떻게 얻습니까?

즉, df2에없는 df1의 모든 행 / 열이있는 데이터 프레임?

여기에 이미지 설명 입력



답변

사용하여 drop_duplicates

pd.concat([df1,df2]).drop_duplicates(keep=False)

Update :

Above method only working for those dataframes they do not have duplicate itself, For example

df1=pd.DataFrame({'A':[1,2,3,3],'B':[2,3,4,4]})
df2=pd.DataFrame({'A':[1],'B':[2]})

아래와 같이 출력됩니다.

잘못된 출력 :

pd.concat([df1, df2]).drop_duplicates(keep=False)
Out[655]:
   A  B
1  2  3

올바른 출력

Out[656]:
   A  B
1  2  3
2  3  4
3  3  4

그것을 달성하는 방법?

방법 1 : isin함께 사용tuple

df1[~df1.apply(tuple,1).isin(df2.apply(tuple,1))]
Out[657]:
   A  B
1  2  3
2  3  4
3  3  4

방법 2 : mergeindicator

df1.merge(df2,indicator = True, how='left').loc[lambda x : x['_merge']!='both']
Out[421]:
   A  B     _merge
1  2  3  left_only
2  3  4  left_only
3  3  4  left_only


답변

행의 경우 다음을 시도하십시오 Name. 결합 인덱스 열은 어디 입니까? (여러 공통 열에 대한 목록이거나 left_on및 지정 가능 right_on) :

m = df1.merge(df2, on='Name', how='outer', suffixes=['', '_'], indicator=True)

indicator=True설정은 “left_only”, “right_only”또는 “both”의 3 가지 종류로 분류 된 및 _merge사이의 모든 변경 사항이있는 이라는 열을 추가하므로 유용합니다 .df1df2

열의 경우 다음을 시도하십시오.

set(df1.columns).symmetric_difference(df2.columns)


답변

허용 된 답변 방법 1은 NaN이 내부에있는 데이터 프레임에 대해 작동하지 않습니다 pd.np.nan != pd.np.nan. 이것이 최선의 방법인지 확실하지 않지만 다음 방법으로 피할 수 있습니다.

df1[~df1.astype(str).apply(tuple, 1).isin(df2.astype(str).apply(tuple, 1))]


답변

edit2, 인덱스 설정없이 새로운 솔루션을 찾았습니다.

newdf=pd.concat([df1,df2]).drop_duplicates(keep=False)

좋아, 나는 가장 높은 투표의 대답에 이미 내가 알아 낸 것을 포함하고 있음을 발견했다. 예, 두 개의 df에 중복이없는 경우에만이 코드를 사용할 수 있습니다.


까다로운 방법이 있습니다. 먼저 질문에서 주어진 두 데이터 프레임의 인덱스로 ‘이름’을 설정합니다. 두 개의 df에 동일한 ‘Name’이 있으므로 ‘bigger’df에서 ‘smaller’df의 인덱스를 삭제할 수 있습니다. 다음은 코드입니다.

df1.set_index('Name',inplace=True)
df2.set_index('Name',inplace=True)
newdf=df1.drop(df2.index)


답변

import pandas as pd
# given
df1 = pd.DataFrame({'Name':['John','Mike','Smith','Wale','Marry','Tom','Menda','Bolt','Yuswa',],
    'Age':[23,45,12,34,27,44,28,39,40]})
df2 = pd.DataFrame({'Name':['John','Smith','Wale','Tom','Menda','Yuswa',],
    'Age':[23,12,34,44,28,40]})

# find elements in df1 that are not in df2
df_1notin2 = df1[~(df1['Name'].isin(df2['Name']) & df1['Age'].isin(df2['Age']))].reset_index(drop=True)

# output:
print('df1\n', df1)
print('df2\n', df2)
print('df_1notin2\n', df_1notin2)

# df1
#     Age   Name
# 0   23   John
# 1   45   Mike
# 2   12  Smith
# 3   34   Wale
# 4   27  Marry
# 5   44    Tom
# 6   28  Menda
# 7   39   Bolt
# 8   40  Yuswa
# df2
#     Age   Name
# 0   23   John
# 1   12  Smith
# 2   34   Wale
# 3   44    Tom
# 4   28  Menda
# 5   40  Yuswa
# df_1notin2
#     Age   Name
# 0   45   Mike
# 1   27  Marry
# 2   39   Bolt


답변

아마도 동일하거나 다른 열 이름을 가진 더 간단한 한 줄짜리 일 것입니다. df2 [ ‘Name2’]에 중복 값이 ​​포함 된 경우에도 작동했습니다.

newDf = df1.set_index('Name1')
           .drop(df2['Name2'], errors='ignore')
           .reset_index(drop=False)


답변

여기
에서 언급했듯이

df1[~df1.apply(tuple,1).isin(df2.apply(tuple,1))]

올바른 솔루션이지만 다음과 같은 경우 잘못된 출력을 생성합니다.

df1=pd.DataFrame({'A':[1],'B':[2]})
df2=pd.DataFrame({'A':[1,2,3,3],'B':[2,3,4,4]})

이 경우 위의 솔루션은 Empty DataFrame 을 제공
하지만 대신 사용해야합니다.concat 각 datframe에서 중복을 제거한 후 메서드 .

사용하다 concate with drop_duplicates

df1=df1.drop_duplicates(keep="first")
df2=df2.drop_duplicates(keep="first")
pd.concat([df1,df2]).drop_duplicates(keep=False)