Pandas Python Filtrando nan a partir de uma seleção de dados de uma coluna de strings


190

Sem usar, groupbycomo eu filtraria os dados sem NaN?

Digamos que eu tenha uma matriz em que os clientes preencham 'N / A', 'n / a' ou qualquer uma de suas variações e outros deixem em branco:

import pandas as pd
import numpy as np


df = pd.DataFrame({'movie': ['thg', 'thg', 'mol', 'mol', 'lob', 'lob'],
                  'rating': [3., 4., 5., np.nan, np.nan, np.nan],
                  'name': ['John', np.nan, 'N/A', 'Graham', np.nan, np.nan]})

nbs = df['name'].str.extract('^(N/A|NA|na|n/a)')
nms=df[(df['name'] != nbs) ]

resultado:

>>> nms
  movie    name  rating
0   thg    John       3
1   thg     NaN       4
3   mol  Graham     NaN
4   lob     NaN     NaN
5   lob     NaN     NaN

Como eu filtraria os valores de NaN para que eu pudesse obter resultados para trabalhar assim:

  movie    name  rating
0   thg    John       3
3   mol  Graham     NaN

Acho que preciso de algo parecido, ~np.isnanmas o tilda não funciona com strings.

Respostas:


254

Apenas solte-os:

nms.dropna(thresh=2)

isso eliminará todas as linhas onde houver pelo menos dois não NaN.

Em seguida, você pode soltar onde está o nome NaN:

In [87]:

nms
Out[87]:
  movie    name  rating
0   thg    John       3
1   thg     NaN       4
3   mol  Graham     NaN
4   lob     NaN     NaN
5   lob     NaN     NaN

[5 rows x 3 columns]
In [89]:

nms = nms.dropna(thresh=2)
In [90]:

nms[nms.name.notnull()]
Out[90]:
  movie    name  rating
0   thg    John       3
3   mol  Graham     NaN

[2 rows x 3 columns]

EDITAR

Na verdade, olhando o que você deseja originalmente, você pode fazer exatamente isso sem a dropnachamada:

nms[nms.name.notnull()]

ATUALIZAR

Olhando para essa pergunta três anos depois, há um erro, primeiramente o thresharg procura pelo menosn não NaNvalores, portanto, a saída deve ser:

In [4]:
nms.dropna(thresh=2)

Out[4]:
  movie    name  rating
0   thg    John     3.0
1   thg     NaN     4.0
3   mol  Graham     NaN

É possível que eu tenha me enganado há 3 anos ou que a versão dos pandas que eu estava executando tenha um bug, ambos os cenários são inteiramente possíveis.


190

Mais simples de todas as soluções:

filtered_df = df[df['name'].notnull()]

Assim, ele filtra apenas as linhas que não possuem valores de NaN na coluna 'nome'.

Para várias colunas:

filtered_df = df[df[['name', 'country', 'region']].notnull().all(1)]

2
Como você consegue isso com várias colunas, organizando-as juntas. 'name' é nulo ou 'foo' é nulo
Greg Hilston 29/03/19

3
@Greg Hilston Use os botões & ou | operador para encadear as condições durante a filtragem. filtered_df = df[df['name'].notnull() | df['foo'].notnull()]
Deepak Rajendran

2
@GregHilston Também adicionei a resposta para sua pergunta. Neste exemplo, estou filtrando valores não nulos de cols como cols = ['nome', 'região', 'país']
Gil Baggio

9
df = pd.DataFrame({'movie': ['thg', 'thg', 'mol', 'mol', 'lob', 'lob'],'rating': [3., 4., 5., np.nan, np.nan, np.nan],'name': ['John','James', np.nan, np.nan, np.nan,np.nan]})

for col in df.columns:
    df = df[~pd.isnull(df[col])]

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.