2016-08-20 12 views
5

Mam dużą ramkę danych z wieloma kolumnami (np. 1000). Mam listę kolumn (generowanych przez skrypt ~ 10). Chciałbym zaznaczyć wszystkie wiersze w oryginalnej ramce danych, w której co najmniej jedna z moich kolumn nie ma wartości null.Wybierz wiersze, w których co najmniej jedna wartość z listy kolumn nie jest pusta.

Więc jeśli chciałbym znać liczbę moich kolumn wcześniej, mógłby zrobić coś takiego:

list_of_cols = ['col1', ...] 
df[ 
    df[list_of_cols[0]].notnull() | 
    df[list_of_cols[1]].notnull() | 
    ... 
    df[list_of_cols[6]].notnull() | 
] 

Mogę również iteracyjne nad listą przełęcze i utworzyć maskę, która to chciałbym zwrócić się do df, ale jego wygląd jest zbyt nużący. Wiedząc, jak potężne są pandy w odniesieniu do radzenia sobie z nan, spodziewam się, że jest łatwiejszy sposób osiągnięcia tego, co chcę.

Odpowiedz

2

pomocą parametru thresh w sposobie dropna(). Ustawiając thresh=1, określasz, że jeśli istnieje co najmniej jeden niezerowy element, nie upuszczaj go.

df = pd.DataFrame(np.random.choice((1., np.nan), (1000, 1000), p=(.3, .7))) 
list_of_cols = list(range(10)) 

df[list_of_cols].dropna(thresh=1).head() 

enter image description here

1

Wychodząc z tego:

data = {'a' :  [np.nan,0,0,0,0,0,np.nan,0,0, 0,0,0, 9,9,], 
    'b' :  [np.nan,np.nan,1,1,1,1,1,1,1, 2,2,2, 1,7], 
    'c' :  [np.nan,np.nan,1,1,2,2,3,3,3, 1,1,1, 1,1], 
    'd' :  [np.nan,np.nan,7,9,6,9,7,np.nan,6, 6,7,6, 9,6]} 

df = pd.DataFrame(data, columns=['a','b','c','d']) 
df 
     a b c d 
0 NaN NaN NaN NaN 
1 0.0 NaN NaN NaN 
2 0.0 1.0 1.0 7.0 
3 0.0 1.0 1.0 9.0 
4 0.0 1.0 2.0 6.0 
5 0.0 1.0 2.0 9.0 
6 NaN 1.0 3.0 7.0 
7 0.0 1.0 3.0 NaN 
8 0.0 1.0 3.0 6.0 
9 0.0 2.0 1.0 6.0 
10 0.0 2.0 1.0 7.0 
11 0.0 2.0 1.0 6.0 
12 9.0 1.0 1.0 9.0 
13 9.0 7.0 1.0 6.0 

Wiersze gdzie nie wszystkie wartości są null. (Usuwanie indeks wiersza 0)

df[~df.isnull().all(axis=1)] 

     a b c d 
1 0.0 NaN NaN NaN 
2 0.0 1.0 1.0 7.0 
3 0.0 1.0 1.0 9.0 
4 0.0 1.0 2.0 6.0 
5 0.0 1.0 2.0 9.0 
6 NaN 1.0 3.0 7.0 
7 0.0 1.0 3.0 NaN 
8 0.0 1.0 3.0 6.0 
9 0.0 2.0 1.0 6.0 
10 0.0 2.0 1.0 7.0 
11 0.0 2.0 1.0 6.0 
12 9.0 1.0 1.0 9.0 
13 9.0 7.0 1.0 6.0 
0

Można użyć boolean indexing

df[~pd.isnull(df[list_of_cols]).all(axis=1)] 

Objaśnienie:

Wyrażenie df[list_of_cols]).all(axis=1) zwraca logiczny układ, który jest stosowany jako filtr do dataframe:

  • isnull() stosowane do df[list_of_cols] tworzy logiczną maskę dataframe df[list_of_cols] z True wartości dla zerowej elementów df[list_of_cols], False inaczej

  • all() powraca True gdy wszystkie elementy są True (w rzędach axis=1)

Tak, przez negację ~ (nie wszystkie null = co najmniej na e ma wartość inną niż null) uzyskuje się maskę dla wszystkich wierszy, które mają co najmniej jeden element inny niż zerowy na podanej liście kolumn.

Przykład:

Dataframe:

>>> df=pd.DataFrame({'A':[11,22,33,np.NaN], 
        'B':['x',np.NaN,np.NaN,'w'], 
        'C':['2016-03-13',np.NaN,'2016-03-14','2016-03-15']}) 
>>> df 
    A B   C 
0 11 x 2016-03-13 
1 22 NaN   NaN 
2 33 NaN 2016-03-14 
3 NaN w 2016-03-15 

isnull maski:

>>> ~pd.isnull(df[list_of_cols]) 
     B  C 
0 True True 
1 False False 
2 False True 
3 True True 

stosuje all(axis=1) w rzędach:

>>> ~pd.isnull(df[list_of_cols]).all(axis=1) 
0  True 
1 False 
2  True 
3  True 
dtype: bool 

logiczny wybór z dataframe:

>>> df[~pd.isnull(df[list_of_cols]).all(axis=1)] 
    A B   C 
0 11 x 2016-03-13 
2 33 NaN 2016-03-14 
3 NaN w 2016-03-15 
+0

Jak mógłbym zatrudnić tego się nie patrzeć na null, ale liczyć wystąpień określonej wartości? Na przykład, biorąc pod uwagę ramkę danych z 10 kolumnami, chcę policzyć liczbę wierszy, w których wartość w pięciu z tych kolumn to "Brakujący/niekompletny". Znalazłem dziesiątki wątków, jak zliczać WSZYSTKIE wartości w każdym wierszu lub kolumnie, ale chcę tylko liczbę, w której wartość dokładnie pasuje do tego ciągu. – Korzak

Powiązane problemy