2017-01-05 11 views
3

У меня есть образец панды dataframe ДФ:Что такое аналог предложения EXCEPT в SQL в Pandas?

 col1 col2 col3 col4 
     0 a  1.0 2.0  3 
     1 b  NaN NaN  6 
     2 c  NaN 8.0  9 
     3 d  NaN 11.0 12 
     4 e  13.0 14.0 15 
     5 f  17.0 18.0 19 
     6 g  21.0 22.0 23 

и второй DF1:

 col1 col2 col3 col4 
     0 a  1.0  2.0  3 
     4 e  13.0 14.0  15 
     5 f  17.0 18.0  19 
     6 g  21.0 22.0  23 

Я хочу, чтобы получить подмножество ФР, не перекрывается с df1. По сути, я ищу эквивалент операнда EXCEPT в SQL.

Я использовал функцию subtract() - но это было явно неправильно, так как вычитание выполняет элементное вычитание. Таким образом, я получил сообщение об ошибке:

 TypeError: unsupported operand type(s) for -: 'str' and 'str' 

Итак, вопрос: что является эквивалентом КРОМЕ в SQL для панд?

+1

Ну ошибка ясно, что вы не можете вычесть строки, кроме того, вы не писали, что желаемый результат должен быть этими вопросами. – EdChum

ответ

5

Я думаю, что вам нужно set_index всех строковых столбцов первых:

df2 = df.set_index('col1').subtract(df1.set_index('col1'), axis='columns') 
print (df2) 
     col2 col3 col4 
col1     
a  0.0 0.0 0.0 
b  NaN NaN NaN 
c  NaN NaN NaN 
d  NaN NaN NaN 
e  0.0 0.0 0.0 
f  0.0 0.0 0.0 
g  0.0 0.0 0.0 

Или:

df2 = df.set_index('col1').subtract(df1.set_index('col1'), axis='columns', fill_value=0) 
print (df2) 
     col2 col3 col4 
col1     
a  0.0 0.0 0.0 
b  NaN NaN 6.0 
c  NaN 8.0 9.0 
d  NaN 11.0 12.0 
e  0.0 0.0 0.0 
f  0.0 0.0 0.0 
g  0.0 0.0 0.0 

EDIT по отредактированной вопрос:

print (df.isin(df1)) 
    col1 col2 col3 col4 
0 True True True True 
1 False False False False 
2 False False False False 
3 False False False False 
4 True True True True 
5 True True True True 
6 True True True True 

print (df.isin(df1).all(axis=1)) 
0  True 
1 False 
2 False 
3 False 
4  True 
5  True 
6  True 
dtype: bool 

print (~df.isin(df1).all(axis=1)) 
0 False 
1  True 
2  True 
3  True 
4 False 
5 False 
6 False 
dtype: bool 

print (df[~(df.isin(df1).all(axis=1))]) 
    col1 col2 col3 col4 
1 b NaN NaN  6 
2 c NaN 8.0  9 
3 d NaN 11.0 12 
+0

Спасибо. Теперь я понимаю, что я использую неправильную функцию. Меня не интересует элементная операция вычитания цифр, а скорее то, что в SQL выполняется предложением EXCEPT. То есть Я хочу получить подмножество df, которое не перекрывается с df1. Вы знаете, как я могу это сделать? – im7

+0

Кажется, вам нужно 'print (df [~ (df.isin (df1) .all (axis = 1))])' - но необходимо выровнять по индексам. – jezrael

+0

Удаляет все строки с одинаковыми значениями с одинаковыми индексами drom 'df'. – jezrael

0

Я думаю, эквивалентный панды для SQL EXCEPT (MINUS) была бы следующая техника:

In [16]: df1 
Out[16]: 
    a b c 
0 1 a 5 # duplicates row with index: 3 
1 0 x 4 
2 9 Z 9 # exists in DF2, so it should NOT appear in the result set 
3 1 a 5 # duplicates row with index: 3 

In [17]: df2 
Out[17]: 
    a b c 
0 66 a 5.0 
1 9 Z 9.0 
2 0 x NaN 

In [18]: (pd.merge(df1, df2, on=df1.columns.tolist(), how='outer', indicator=True) 
    ...: .query("_merge == 'left_only'") 
    ...: .drop('_merge', 1) 
    ...:) 
    ...: 
Out[18]: 
    a b c 
0 1 a 5.0 
1 1 a 5.0 
2 0 x 4.0 

Примечание: это решение не обращать внимание на индексах