Como definir uma célula para NaN em um dataframe do pandas

97

Eu gostaria de substituir valores inválidos em uma coluna de um dataframe por NaN's.

mydata = {'x' : [10, 50, 18, 32, 47, 20], 'y' : ['12', '11', 'N/A', '13', '15', 'N/A']}
df = pd.DataFrame(mydata)

df[df.y == 'N/A']['y'] = np.nan

Porém, a última linha falha e gera um aviso porque está trabalhando em uma cópia do df. Então, qual é a maneira correta de lidar com isso? Já vi muitas soluções com iloc ou ix, mas aqui, preciso usar uma condição booleana.

Mark Morrisson
fonte

Respostas:

122

apenas use replace:

In [106]:
df.replace('N/A',np.NaN)

Out[106]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN

O que você está tentando é chamado de indexação em cadeia: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

Você pode usar locpara garantir que opera no dF original:

In [108]:
df.loc[df['y'] == 'N/A','y'] = np.nan
df

Out[108]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN
EdChum
fonte
13

Embora o uso replacepareça resolver o problema, gostaria de propor uma alternativa. Problema com a combinação de valores numéricos e alguns valores de string na coluna para não ter strings substituídas por np.nan, mas para tornar a coluna inteira adequada. Eu apostaria que a coluna original provavelmente é de um tipo de objeto

Name: y, dtype: object

O que você realmente precisa é torná-la uma coluna numérica (ela terá o tipo adequado e seria bem mais rápida), com todos os valores não numéricos substituídos por NaN.

Assim, um bom código de conversão seria

pd.to_numeric(df['y'], errors='coerce')

Especifique errors='coerce'para forçar strings que não podem ser analisadas em um valor numérico para se tornarem NaN. O tipo de coluna seria

Name: y, dtype: float64
Severin Pappadeux
fonte
10

Você pode usar substituir:

df['y'] = df['y'].replace({'N/A': np.nan})

Esteja ciente também do inplaceparâmetro para replace. Você pode fazer algo como:

df.replace({'N/A': np.nan}, inplace=True)

Isso substituirá todas as instâncias no df sem criar uma cópia.

Da mesma forma, se você encontrar outros tipos de valores desconhecidos, como string vazia ou valor Nenhum:

df['y'] = df['y'].replace({'': np.nan})

df['y'] = df['y'].replace({None: np.nan})

Referência: Pandas Latest - Replace

Jmorrison
fonte
1
df.loc[df.y == 'N/A',['y']] = np.nan

Isso resolve seu problema. Com duplo [], você está trabalhando em uma cópia do DataFrame. Você deve especificar o local exato em uma chamada para poder modificá-lo.

jeremie benichou
fonte
0

Você pode tentar esses trechos.

Em [16]: mydata = {'x': [10, 50, 18, 32, 47, 20], 'y': ['12', '11', 'N / A', '13', ' 15 ',' N / A ']}
Em [17]: df = pd.DataFrame (mydata)

Em [18]: df.y [df.y == "N / A"] = np.nan

Fora [19]: df 
    xy
0 10 12
1 50 11
2 18 NaN
3 32 13
4 47 15
5 20 NaN
Rolandpeng
fonte
0

A partir do pandas 1.0.0, você não precisa mais usar numpy para criar valores nulos em seu dataframe. Em vez disso, você pode apenas usar pandas.NA (que é do tipo pandas._libs.missing.NAType), então ele será tratado como nulo dentro do dataframe, mas não será nulo fora do contexto do dataframe.

slevin886
fonte