2016-04-18 2 views
0

У меня есть dataframe, который выглядит, как этотже наблюдение в нескольких столбцах

ID1  ID2 variables 
    a  b  something 
    b  g  something 
    c  h  something 
    d  i  something 
    a  h  something 

Если идентификатор отображается в обоих ID1 и ID2 Я хочу наблюдение этого значения в ID1 должны быть исключены из набора данных. Так что в этом случае

ID1  ID2 variables 
    a  b  something  
    c  h  something 
    d  i  something 
    a  h  something 

Что я считал:

Там может быть несколько наблюдений одного и того же ID. Переименование, конкатенация и удаление дубликатов не будут работать.

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

ответ

3

Проверьте ID1 имеет isin значения из ID2 и поместите их с помощью .loc разрезание для фильтрации данных.

In [76]: df.loc[~df['ID1'].isin(df['ID2']), :] 
Out[76]: 
    ID1 ID2 variables 
0 a b something 
2 c h something 
3 d i something 
4 a h something 

Детали:

In [77]: df 
Out[77]: 
    ID1 ID2 variables 
0 a b something 
1 b g something 
2 c h something 
3 d i something 
4 a h something 

In [78]: ~df['ID1'].isin(df['ID2']) 
Out[78]: 
0  True 
1 False 
2  True 
3  True 
4  True 
Name: ID1, dtype: bool 

In [79]: df.loc[~df['ID1'].isin(df['ID2']), :] 
Out[79]: 
    ID1 ID2 variables 
0 a b something 
2 c h something 
3 d i something 
4 a h something 
1

Я думаю, что вы можете использовать isin с инвертирующим булевой Series по ~ с boolean indexing:

print df.ID1.isin(df.ID2) 
0 False 
1  True 
2 False 
3 False 
4 False 

print ~df.ID1.isin(df.ID2) 
0  True 
1 False 
2  True 
3  True 
4  True 
Name: ID1, dtype: bool 

print df[~df.ID1.isin(df.ID2)] 
    ID1 ID2 variables 
0 a b something 
2 c h something 
3 d i something 
4 a h something 

ТЕСТИРОВАНИЕ:

df = pd.concat([df]*100000).reset_index(drop=True) 

In [157]: %timeit df.loc[~df['ID1'].isin(df['ID2']), :] 
10 loops, best of 3: 55.5 ms per loop 

In [158]: %timeit df[~df.ID1.isin(df.ID2)] 
10 loops, best of 3: 55 ms per loop 
1

самый простой способ может быть

df.query('ID1 not in ID2') 
Смежные вопросы