반조류 판다
저는 두 개의 테이블을 가지고 있는데 테이블 A의 모든 데이터만 유지되고 테이블 B의 데이터는 키가 유일한 경우에만 추가되도록 추가하고 싶습니다(키 값은 테이블 A와 B에서 유일하지만 경우에 따라서는 테이블 A와 B 모두에서 키가 발생합니다).
이 방법은 표 A에서 발생하지 않는 표 B의 값을 얻고 두 개의 표를 추가하는 일종의 필터링 조인(Anti-join)을 포함할 것이라고 생각합니다.
저는 R을 잘 알고 있고 이것이 제가 R에서 이것을 할 때 사용할 코드입니다.
library("dplyr")
## Filtering join to remove values already in "TableA" from "TableB"
FilteredTableB <- anti_join(TableB,TableA, by = "Key")
## Append "FilteredTableB" to "TableA"
CombinedTable <- bind_rows(TableA,FilteredTableB)
파이썬에서 이걸 어떻게 달성할 수 있을까요?
indicator = True인에merge명령어는 새 열을 만들어 어떤 조인을 적용했는지 알려줍니다._merge다음 세 가지 가능한 값을 사용합니다.
left_onlyright_onlyboth
지킨다right_only그리고.left_only. 여기까지입니다.
outer_join = TableA.merge(TableB, how = 'outer', indicator = True)
anti_join = outer_join[~(outer_join._merge == 'both')].drop('_merge', axis = 1)
쉬우세요!
다음은 piRSquare의 솔루션과 비교한 것입니다.
1) 하나의 열을 기준으로 이 예제 매칭에서 실행하면 piRSquare의 솔루션이 더 빠릅니다.
2) 단, 한 열에 대해서만 매칭이 가능합니다.여러 개의 열에 대해 일치시키려면 한 개의 열에 대해서만 해결할 수 있습니다.
당신이 결정할 문제입니다.
다음 데이터 프레임을 고려합니다.
TableA = pd.DataFrame(np.random.rand(4, 3),
pd.Index(list('abcd'), name='Key'),
['A', 'B', 'C']).reset_index()
TableB = pd.DataFrame(np.random.rand(4, 3),
pd.Index(list('aecf'), name='Key'),
['A', 'B', 'C']).reset_index()
TableA
TableB
이것이 당신이 원하는 것을 할 수 있는 하나의 방법입니다.
방법1
# Identify what values are in TableB and not in TableA
key_diff = set(TableB.Key).difference(TableA.Key)
where_diff = TableB.Key.isin(key_diff)
# Slice TableB accordingly and append to TableA
TableA.append(TableB[where_diff], ignore_index=True)
방법2
rows = []
for i, row in TableB.iterrows():
if row.Key not in TableA.Key.values:
rows.append(row)
pd.concat([TableA.T] + rows, axis=1).T
타이밍.
두 개의 겹침이 있는 4개의 행
방법 1이 훨씬 빠릅니다.
10,000 행 5,000 겹침
루프가 나쁩니다.
저도 같은 문제가 있었습니다.를 이용한 답변입니다.how='outer'그리고.indicator=True제가 이 솔루션을 생각해 내도록 영감을 주었습니다.
import pandas as pd
import numpy as np
TableA = pd.DataFrame(np.random.rand(4, 3),
pd.Index(list('abcd'), name='Key'),
['A', 'B', 'C']).reset_index()
TableB = pd.DataFrame(np.random.rand(4, 3),
pd.Index(list('aecf'), name='Key'),
['A', 'B', 'C']).reset_index()
print('TableA', TableA, sep='\n')
print('TableB', TableB, sep='\n')
TableB_only = pd.merge(
TableA, TableB,
how='outer', on='Key', indicator=True, suffixes=('_foo','')).query(
'_merge == "right_only"')
print('TableB_only', TableB_only, sep='\n')
Table_concatenated = pd.concat((TableA, TableB_only), join='inner')
print('Table_concatenated', Table_concatenated, sep='\n')
다음 출력을 인쇄합니다.
TableA
Key A B C
0 a 0.035548 0.344711 0.860918
1 b 0.640194 0.212250 0.277359
2 c 0.592234 0.113492 0.037444
3 d 0.112271 0.205245 0.227157
TableB
Key A B C
0 a 0.754538 0.692902 0.537704
1 e 0.499092 0.864145 0.004559
2 c 0.082087 0.682573 0.421654
3 f 0.768914 0.281617 0.924693
TableB_only
Key A_foo B_foo C_foo A B C _merge
4 e NaN NaN NaN 0.499092 0.864145 0.004559 right_only
5 f NaN NaN NaN 0.768914 0.281617 0.924693 right_only
Table_concatenated
Key A B C
0 a 0.035548 0.344711 0.860918
1 b 0.640194 0.212250 0.277359
2 c 0.592234 0.113492 0.037444
3 d 0.112271 0.205245 0.227157
4 e 0.499092 0.864145 0.004559
5 f 0.768914 0.281617 0.924693
상상할 수 있는 가장 쉬운 대답:
tableB = pd.concat([tableB, pd.Series(1)], axis=1)
mergedTable = tableA.merge(tableB, how="left" on="key")
answer = mergedTable[mergedTable.iloc[:,-1].isnull()][tableA.columns.tolist()]
또한 가장 빨리 제안되어야 합니다.
원라이너
TableA.append(TableB.loc[~TableB.Key.isin(TableA.Key)], ignore_index=True)
%%timeit허용된 답변과 거의 동일한 타이밍을 제공합니다.
두 테이블이 다 있습니다.TableA그리고.TableB둘 다가 되도록DataFrame개체에는 해당 테이블에 고유한 값을 가진 열이 있지만 일부 열에는 두 테이블에서 동시에 발생하는 값(행에 대해 동일한 값)이 있을 수 있습니다.
그런 다음에 행을 병합합니다.TableA줄을 늘어놓고TableB어떤 것과도 일치하지 않는TableA'Key' 열에 입력합니다.개념은 두 시리즈의 변수 길이를 비교하고 한 시리즈의 행을 결합하는 것으로 그림을 그리는 것입니다.sA다른 쪽과 함께sB한다면sB의 가치관이 일치하지 않습니다.sA의 s. 다음 코드가 이 연습 문제를 해결합니다.
import pandas as pd
TableA = pd.DataFrame([[2, 3, 4], [5, 6, 7], [8, 9, 10]])
TableB = pd.DataFrame([[1, 3, 4], [5, 7, 8], [9, 10, 0]])
removeTheseIndexes = []
keyColumnA = TableA.iloc[:,1] # your 'Key' column here
keyColumnB = TableB.iloc[:,1] # same
for i in range(0, len(keyColumnA)):
firstValue = keyColumnA[i]
for j in range(0, len(keyColumnB)):
copycat = keyColumnB[j]
if firstValue == copycat:
removeTheseIndexes.append(j)
TableB.drop(removeTheseIndexes, inplace = True)
TableA = TableA.append(TableB)
TableA = TableA.reset_index(drop=True)
이것은 영향을 끼칩니다.TableB의 데이터도 마찬가지입니다.사용가능inplace=FalseA로 다시 assign합니다.newTable,그리고나서TableA.append(newTable)교대로
# Table A
0 1 2
0 2 3 4
1 5 6 7
2 8 9 10
# Table B
0 1 2
0 1 3 4
1 5 7 8
2 9 10 0
# Set 'Key' column = 1
# Run the script after the loop
# Table A
0 1 2
0 2 3 4
1 5 6 7
2 8 9 10
3 5 7 8
4 9 10 0
# Table B
0 1 2
1 5 7 8
2 9 10 0
다른 제안들 중 하나를 바탕으로, 여기 그것을 수행해야 하는 기능이 있습니다.팬더 기능만 사용하면 루프가 없습니다.여러 열을 키로 사용할 수도 있습니다.라인을 바꾸면output = merged.loc[merged.dummy_col.isna(),tableA.columns.tolist()] .output = merged.loc[~merged.dummy_col.isna(),tableA.columns.tolist()] 당신은 세미 join을 가지고 있습니다.
def anti_join(tableA,tableB,on):
#if joining on index, make it into a column
if tableB.index.name is not None:
dummy = tableB.reset_index()[on]
else:
dummy = tableB[on]
#create a dummy columns of 1s
if isinstance(dummy, pd.Series):
dummy = dummy.to_frame()
dummy.loc[:,'dummy_col'] = 1
#preserve the index of tableA if it has one
if tableA.index.name is not None:
idx_name = tableA.index.name
tableA = tableA.reset_index(drop = False)
else:
idx_name = None
#do a left-join
merged = tableA.merge(dummy,on=on,how='left')
#keep only the non-matches
output = merged.loc[merged.dummy_col.isna(),tableA.columns.tolist()]
#reset the index (if applicable)
if idx_name is not None:
output = output.set_index(idx_name)
return(output)
언급URL : https://stackoverflow.com/questions/38516664/anti-join-pandas
'programing' 카테고리의 다른 글
| x86_64 va_list 구조의 형식은 무엇입니까? (0) | 2023.10.26 |
|---|---|
| JavaScript에서 프로토타입 상속 이해 (0) | 2023.10.26 |
| @AttributeOverride가 있는 @Embeddable 항목의 JPA @ElementCollection (0) | 2023.10.26 |
| 문자열 벡터에 대한 조인 연산자의 동등성은 무엇입니까? (0) | 2023.10.26 |
| PowerShell - 고유 값 필터링 (0) | 2023.10.26 |





