2014-11-15 4 views
2

다른 데이터 프레임의 데이터를 기반으로 한 데이터 프레임에서 데이터를 제거하고 싶습니다. 이 작업을 수행하는 방법을 찾았지만 (아래 참조) 더 효율적인 방법이 있는지 궁금합니다. python/pandas에서 왼쪽 내부 조인하는 법?

# -*- coding: utf-8 -*- 

import pandas as pd 

#df1 is the dataframe where I want to remove data from 
d1 = {'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.], 'three' : [5.,6.,7.,8.] } 
df1 = pd.DataFrame(d1) 
df1.columns = ['one', 'two', 'three'] #Keeping the order of the columns as defined 
print 'df1\n', df1 
#print df1 

#I want to remove all the rows from df1 that are also in df2 
d2 = {'one' : [2., 4.], 'two' : [3., 1], 'three' : [6.,8.] } 
df2 = pd.DataFrame(d2) 
df2.columns = ['one', 'two', 'three'] #Keeping the order of the columns as defined 
print 'df2\n', df2 


#df3 is the output I want to get: it should have the same data as df1, but without the data that is in df2 
df3 = df1 

#Create some keys to help identify rows to be dropped from df1 
df1['key'] = df1['one'].astype(str)+'-'+df1['two'].astype(str)+'-'+df1['three'].astype(str) 
print 'df1 with key\n', df1 
df2['key'] = df2['one'].astype(str)+'-'+df2['two'].astype(str)+'-'+df2['three'].astype(str) 
print 'df2 with key\n', df2 

#List of rows to remove from df1 
rowsToDrop = [] 

#Building the list of rows to drop 
for i in df1.index: 
    if df1['key'].irow(i) in df2.ix[:,'key'].values: 
     rowsToDrop.append(i) 

#Dropping rows from df1 that are also in df2 
for j in reversed(rowsToDrop): 
    df3 = df3.drop(df3.index[j]) 

df3.drop(['key'], axis=1, inplace=True)   

#Voilà! 
print 'df3\n', df3 

여러분의 도움에 감사드립니다 : 는 여기에 내가 향상시키고 자하는 코드입니다.

+0

당신이 말할 때'DF3 = df1', 'df3'는'df1'과 *의 변경을 반영합니다. 'df3 = df1.copy()'라고 대신 말해야한다. –

+0

또한이 작업은 실제로 조인 작업이 아닙니다. 그것은 선택입니다. 나는 그것을 반영하기 위해 제목을 편집해야한다고 생각합니다. –

+0

내가하려는 것은이 웹 사이트 http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins에서 "left exclude join"을 호출하는 것입니다. –

답변

1

이 당신은 (ISIN하는 DF를 전달할 수 있습니다

df3 = df1[~df1.isin(d2)].dropna() 

데이터 프레임 DF1과 DICT의 D2)를 사용하여 작동하지만 나는 당신이 당신에게 당신이 찾고있는 결과를 얻을 수 있다고 생각하지 않습니다 왜냐하면 나는 그것이 인덱스를 보았 기 때문입니다. 당신은 dataframes에 가입하지 행을 선택하기위한 구문 더 찾고

http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.isin.html

+0

감사합니다. Bob. 귀하의 제안은 실제로 훨씬 더 콤팩트합니다. 실행하는 데 거의 같은 시간이 걸리는 것 같습니다. –

0

. '

진정한 왼쪽과 같을 것이다 가입 :

import numpy as np 
import pandas as pd 

d1 = {'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.], 'three' : [5.,6.,7.,8.] } 
df1 = pd.DataFrame(d1) 
df1['key'] = df1['one'].astype(str)+'-'+df1['two'].astype(str)+'-'+df1['three'].astype(str) 
df1.set_index('key', inplace=True) 


d2 = {'one' : [2., 4.], 'two' : [3., 1], 'three' : [6.,8.] } 
df2 = pd.DataFrame(d2) 
df2['key'] = df2['one'].astype(str)+'-'+df2['two'].astype(str)+'-'+df2['three'].astype(str) 
df2.set_index('key', inplace=True) 

df1.join(df2, how='left', lsuffix='_df1', rsuffix='_df2') 


      one_df1 three_df1 two_df1 one_df2 three_df2 two_df2 
key                 
1.0-4.0-5.0  1   5  4  NaN  NaN  NaN 
2.0-3.0-6.0  2   6  3  2   6  3 
3.0-2.0-7.0  3   7  2  NaN  NaN  NaN 
4.0-1.0-8.0  4   8  1  4   8  1 

이 권리를하는 가입 :

df1.join(df2, how='right', lsuffix='_df1', rsuffix='_df2') 

이 생산 :

   one_df1 three_df1 two_df1 one_df2 three_df2 two_df2 
key                 
2.0-3.0-6.0  2   6  3  2   6  3 
4.0-1.0-8.0  4   8  1  4   8  1 
+0

폴 감사합니다. 예 DataFrame.join()을 보았지만 df2의 행이 출력에 남아 있기 때문에이 경우 원하는 것을 제공하지 않습니다. –

+0

@TonyMignot 나도 알아 - 내 요점은 당신이 실제로 조인 작업을 원하지 않기 때문에 실제로 원하는 것을 더 잘 반영하기 위해 질문의 제목을 편집해야한다는 것입니다. 또한'.dropna()'를 사용하여 해당 행을 제거하거나'right' join을 사용할 수 있습니다. –

+0

@TonyMignot 내 편집보기 –

관련 문제