2017-01-04 53 views
5

Mam pandas.Series, gdzie typ d dla każdego wiersza jest obiektem listy. Na przykład.Jak usunąć NaN z serii Pandas, gdzie dtype jest listą?

>>> import numpy as np 
>>> import pandas as pd 
>>> x = pd.Series([[1,2,3], [2,np.nan], [3,4,5,np.nan], [np.nan]]) 
>>> x 
0   [1, 2, 3] 
1   [2, nan] 
2 [3, 4, 5, nan] 
3    [nan] 
dtype: object 

Jak usunąć nan z list dla każdego rzędu?

pożądany wynik byłby:

>>> x 
0   [1, 2, 3] 
1    [2] 
2   [3, 4, 5] 
3    [] 
dtype: object 

to działa:

>>> x.apply(lambda y: pd.Series(y).dropna().values.tolist()) 
0   [1, 2, 3] 
1    [2.0] 
2 [3.0, 4.0, 5.0] 
3     [] 
dtype: object 

Czy istnieje prostszy sposób niż przy użyciu lambda, konwersja do listy do serii, upuszczając NaN a następnie ekstrakcji wartości ponownie powrócić do listy?

Odpowiedz

5

Można użyć list comprehension z pandas.notnull dla usuń NaN wartości:

print (x.apply(lambda y: [a for a in y if pd.notnull(a)])) 
0 [1, 2, 3] 
1   [2] 
2 [3, 4, 5] 
3   [] 
dtype: object 

Innym rozwiązaniem z filter ze stanu, w którym v!=v tylko dla NaN:

print (x.apply(lambda a: list(filter(lambda v: v==v, a)))) 
0 [1, 2, 3] 
1   [2] 
2 [3, 4, 5] 
3   [] 
dtype: object 

Dziękuję DYZ innego rozwiązania:

print (x.apply(lambda y: list(filter(np.isfinite, y)))) 
0 [1, 2, 3] 
1   [2] 
2 [3, 4, 5] 
3   [] 
dtype: object 
+0

'lambda' i' if-else' warunki powinien móc zostać uproszczone w 'filter', nie? – alvas

+0

Tak, masz rację. Dodaję rozwiązanie. – jezrael

+0

@jezrael Rozwiązanie z jednym 'lambda':' x.apply (lambda y: list (filter (np.isfinite, y))) '. – DyZ

1

Prosty numpy rozwiązanie z listowego:

pd.Series([np.array(e)[~np.isnan(e)] for e in x.values])