Python панды удаляют повторяющиеся строки, которые имеют значение столбца "NaN" - PullRequest
0 голосов
/ 21 ноября 2018

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

    A   B   C
0   foo 2   3
1   foo nan nan
2   foo 1   4
3   bar nan nan
4   foo nan nan

Должна стать такой:

    A   B   C
0   foo 2   3
2   foo 1   4
3   bar nan nan

Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Немного отличается от решения Jezrael:

>>> df                                                                                                     
     A    B    C
0  foo  2.0  3.0
1  foo  NaN  NaN
2  foo  1.0  4.0
3  bar  NaN  NaN
4  foo  NaN  NaN
>>>
>>> df.drop(index=df[df.duplicated(keep=False)].isnull().any(1).index)                                  
     A    B    C
0  foo  2.0  3.0
2  foo  1.0  4.0
3  bar  NaN  NaN

Шаги:

>>> df.duplicated(keep=False)                                                                            
0    False
1     True
2    False
3    False
4     True
dtype: bool
>>>
>>> df[df.duplicated(keep=False)]                                                                       
      A   B   C
1  foo NaN NaN
4  foo NaN NaN
>>>
>>> df[df.duplicated(keep=False)].isnull()                                                                 
       A     B     C
1  False  True  True
4  False  True  True
>>>
>>> df[df.duplicated(keep=False)].isnull().any(1).index                                                          
Int64Index([1, 4], dtype='int64')
0 голосов
/ 21 ноября 2018

Использование boolean indexing:

df = df[~df['A'].duplicated(keep=False) | df[['B','C']].notnull().any(axis=1)]
print (df)
     A    B    C
0  foo  2.0  3.0
2  foo  1.0  4.0
3  bar  NaN  NaN

Пояснение :

Тестовая колонка A для неповторяющихся - duplicated с ~ для инвертированной логической маски:

print (~df['A'].duplicated(keep=False))
0    False
1    False
2    False
3     True
4    False
Name: A, dtype: bool

Проверка не пропущенных значений в столбцах B,C:

print (df[['B','C']].notnull())
       B      C
0   True   True
1  False  False
2   True   True
3  False  False
4  False  False

И затем по крайней мере один True в строкес DataFrame.any:

print (df[['B','C']].notnull().any(axis=1))
0     True
1    False
2     True
3    False
4    False
dtype: bool

Цепочка по | для побитового OR:

print (~df['A'].duplicated(keep=False) | df[['B','C']].notnull().any(axis=1))
0     True
1    False
2     True
3     True
4    False
dtype: bool
...