팬더는 다른 데이터 프레임에없는 행을 얻습니다.
공통으로 일부 행이있는 두 개의 팬더 데이터 프레임이 있습니다.
dataframe2가 dataframe1의 서브 세트라고 가정하십시오.
dataframe2에없는 dataframe1의 행을 어떻게 얻을 수 있습니까?
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})
한 가지 방법은 내부 병합 양식의 결과를 두 df로 저장하는 것입니다. 그런 다음 하나의 열 값이이 공통 값이 아닌 경우 간단히 행을 선택할 수 있습니다.
In [119]:
common = df1.merge(df2,on=['col1','col2'])
print(common)
df1[(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))]
col1 col2
0 1 10
1 2 11
2 3 12
Out[119]:
col1 col2
3 4 13
4 5 14
편집하다
당신이 찾은 또 다른 방법 은 삭제할 수있는 행을 isin
생성 하는 사용 하는 것입니다 NaN
.
In [138]:
df1[~df1.isin(df2)].dropna()
Out[138]:
col1 col2
3 4 13
4 5 14
그러나 df2가 같은 방식으로 행을 시작하지 않으면 작동하지 않습니다.
df2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11, 12,13]})
전체 df를 생성합니다.
In [140]:
df1[~df1.isin(df2)].dropna()
Out[140]:
col1 col2
0 1 10
1 2 11
2 3 12
3 4 13
4 5 14
현재 선택된 솔루션이 잘못된 결과를 생성합니다. 제대로이 문제를 해결하기 위해, 우리는이에서 왼쪽 조인을 수행 할 수 있습니다 df1
에 df2
처음만을위한 고유 행을 얻을 수 있는지에있어 df2
.
먼저, 데이터가있는 행을 추가하기 위해 원본 DataFrame을 수정해야합니다 [3, 10].
df1 = pd.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3],
'col2' : [10, 11, 12, 13, 14, 10]})
df2 = pd.DataFrame(data = {'col1' : [1, 2, 3],
'col2' : [10, 11, 12]})
df1
col1 col2
0 1 10
1 2 11
2 3 12
3 4 13
4 5 14
5 3 10
df2
col1 col2
0 1 10
1 2 11
2 3 12
왼쪽 조인을 수행하여 df2
각 행이 df1
정확히 1 행의 조인 되도록 중복을 제거하십시오 df2
. 매개 변수 indicator
를 사용하여 행이 어느 테이블에서 왔는지 나타내는 추가 열을 리턴 하십시오 .
df_all = df1.merge(df2.drop_duplicates(), on=['col1','col2'],
how='left', indicator=True)
df_all
col1 col2 _merge
0 1 10 both
1 2 11 both
2 3 12 both
3 4 13 left_only
4 5 14 left_only
5 3 10 left_only
부울 조건을 만듭니다.
df_all['_merge'] == 'left_only'
0 False
1 False
2 False
3 True
4 True
5 True
Name: _merge, dtype: bool
다른 솔루션이 잘못된 이유
일부 솔루션은 동일한 실수를합니다. 각 값이 동일한 행이 아니라 각 열에 독립적으로 있는지 확인합니다. 고유하지만 두 열의 값이있는 마지막 행을 추가하면 df2
실수 가 노출됩니다.
common = df1.merge(df2,on=['col1','col2'])
(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))
0 False
1 False
2 False
3 True
4 True
5 False
dtype: bool
이 솔루션은 동일한 잘못된 결과를 얻습니다.
df1.isin(df2.to_dict('l')).all(1)
인덱스가 데이터 프레임에서 일관성이 있다고 가정하면 (실제 col 값을 고려하지 않음) :
df1[~df1.index.isin(df2.index)]
As already hinted at, isin requires columns and indices to be the same for a match. If match should only be on row contents, one way to get the mask for filtering the rows present is to convert the rows to a (Multi)Index:
In [77]: df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3], 'col2' : [10, 11, 12, 13, 14, 10]})
In [78]: df2 = pandas.DataFrame(data = {'col1' : [1, 3, 4], 'col2' : [10, 12, 13]})
In [79]: df1.loc[~df1.set_index(list(df1.columns)).index.isin(df2.set_index(list(df2.columns)).index)]
Out[79]:
col1 col2
1 2 11
4 5 14
5 3 10
If index should be taken into account, set_index has keyword argument append to append columns to existing index. If columns do not line up, list(df.columns) can be replaced with column specifications to align the data.
pandas.MultiIndex.from_tuples(df<N>.to_records(index = False).tolist())
could alternatively be used to create the indices, though I doubt this is more efficient.
Suppose you have two dataframes, df_1 and df_2 having multiple fields(column_names) and you want to find the only those entries in df_1 that are not in df_2 on the basis of some fields(e.g. fields_x, fields_y), follow the following steps.
Step1.Add a column key1 and key2 to df_1 and df_2 respectively.
Step2.Merge the dataframes as shown below. field_x and field_y are our desired columns.
Step3.Select only those rows from df_1 where key1 is not equal to key2.
Step4.Drop key1 and key2.
This method will solve your problem and works fast even with big data sets. I have tried it for dataframes with more than 1,000,000 rows.
df_1['key1'] = 1
df_2['key2'] = 1
df_1 = pd.merge(df_1, df_2, on=['field_x', 'field_y'], how = 'left')
df_1 = df_1[~(df_1.key2 == df_1.key1)]
df_1 = df_1.drop(['key1','key2'], axis=1)
a bit late, but it might be worth checking the "indicator" parameter of pd.merge.
See this other question for an example: Compare PandaS DataFrames and return rows that are missing from the first one
you can do it using isin(dict) method:
In [74]: df1[~df1.isin(df2.to_dict('l')).all(1)]
Out[74]:
col1 col2
3 4 13
4 5 14
Explanation:
In [75]: df2.to_dict('l')
Out[75]: {'col1': [1, 2, 3], 'col2': [10, 11, 12]}
In [76]: df1.isin(df2.to_dict('l'))
Out[76]:
col1 col2
0 True True
1 True True
2 True True
3 False False
4 False False
In [77]: df1.isin(df2.to_dict('l')).all(1)
Out[77]:
0 True
1 True
2 True
3 False
4 False
dtype: bool
You can also concat df1
, df2
:
x = pd.concat([df1, df2])
and then remove all duplicates:
y = x.drop_duplicates(keep=False, inplace=False)
How about this:
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5],
'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3],
'col2' : [10, 11, 12]})
records_df2 = set([tuple(row) for row in df2.values])
in_df2_mask = np.array([tuple(row) in records_df2 for row in df1.values])
result = df1[~in_df2_mask]
Here is another way of solving this:
df1[~df1.index.isin(df1.merge(df2, how='inner', on=['col1', 'col2']).index)]
Or:
df1.loc[df1.index.difference(df1.merge(df2, how='inner', on=['col1', 'col2']).index)]
My way of doing this involves adding a new column that is unique to one dataframe and using this to choose whether to keep an entry
df2[col3] = 1
df1 = pd.merge(df_1, df_2, on=['field_x', 'field_y'], how = 'outer')
df1['Empt'].fillna(0, inplace=True)
This makes it so every entry in df1 has a code - 0 if it is unique to df1, 1 if it is in both dataFrames. You then use this to restrict to what you want
answer = nonuni[nonuni['Empt'] == 0]
참고URL : https://stackoverflow.com/questions/28901683/pandas-get-rows-which-are-not-in-other-dataframe
'Programing' 카테고리의 다른 글
전 처리기 지시문으로 OS를 어떻게 확인합니까? (0) | 2020.05.26 |
---|---|
왜 Java의 Iterator가 Iterable이 아닌가? (0) | 2020.05.26 |
Git 프로젝트의 모든 개발자 목록 (0) | 2020.05.26 |
두 벡터를 연결하는 가장 좋은 방법은 무엇입니까? (0) | 2020.05.26 |
MySQL 테이블이 마지막으로 업데이트 된 시점을 어떻게 알 수 있습니까? (0) | 2020.05.26 |