Как удалить строки, которые появляются одинаково в двух столбцах одновременно в кадре данных? - PullRequest
2 голосов
/ 11 марта 2020

У меня есть Dataframe, DF1

   Id1   Id2  
0  286   409 
1  286   257  
2  409   286    
3  257   183   

В этом DF для меня строки 286,409 и 409,286 одинаковы. Я хочу оставить только один из этих рядов. Все, что я делаю, - это строю сетевой граф, используя библиотеку Networkx python.

Я пытался добиться этого путем создания другого df с переставленными столбцами, например, DF2

   Id2   Id1
0  409   286
1  257   286
2  286   409
3  183   257

затем я сравниваю эти два DF с использованием функции isin примерно так:

DF1[DF1[['Id1', 'Id2']].isin(DF2[['Id2', 'Id1']])], но она печатает DF1, как было.

Ожидаемый выходной DF:

   Id1   Id2  
0  286   409 
1  286   257     
3  257   183  

Любая помощь будет оценена, спасибо.

Ответы [ 2 ]

1 голос
/ 11 марта 2020

Вы можете сгруппировать свой DataFrame по отсортированному списку значений столбцов

import pandas as pd
from io import StringIO

data = """Id1   Id2
286   409
286   257
409   286
257   183"""

df = pd.read_csv(StringIO(data), sep="\s+")

print(df.groupby(df.apply(lambda x: str(sorted(list(x))), axis=1)).first())

Результат:

            Id1  Id2
[183, 257]  257  183
[257, 286]  286  257
[286, 409]  286  409
1 голос
/ 11 марта 2020

Полагаю, вам нужно отсортировать оба столбца по np.sort и отфильтровать по DataFrame.duplicated с обратной маской:

df1 = pd.DataFrame(np.sort(DF1[['Id1', 'Id2']].to_numpy(), axis=1), index=DF1.index)

df = DF1[~df1.duplicated()]
print (df)
   Id1  Id2
0  286  409
1  286  257
3  257  183

Detail : при использовании numpy.sort с axis=1 сортировка по строкам, поэтому первый и третий 'row' одинаковы:

print (np.sort(DF1[['Id1', 'Id2']].to_numpy(), axis=1))
[[286 409]
 [257 286]
 [286 409]
 [183 257]]

Затем используйте функцию DataFrame.duplicated (работает с DataFrame, поэтому используется конструктор DataFrame):

df1 = pd.DataFrame(np.sort(DF1[['Id1', 'Id2']].to_numpy(), axis=1), index=DF1.index)
print (df1)
     0    1
0  286  409
1  257  286
2  286  409
3  183  257

Третье значение является дубликатом:

print (df1.duplicated())
0    False
1    False
2     True
3    False
dtype: bool

Последнее - необходимая инвертирующая маска для удаления дубликатов, выходные данные фильтруются в boolean indexing:

print (DF1[~df1.duplicated()])
   Id1  Id2
0  286  409
1  286  257
3  257  183
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...