DataFrame do pandas: substitua os valores nan pela média de colunas

177

Eu tenho um DataFrame de pandas preenchido principalmente com números reais, mas também existem alguns nanvalores.

Como posso substituir os nans com médias de colunas onde eles estão?

Essa pergunta é muito semelhante a esta: matriz numpy: substitui os valores nan pela média de colunas , mas, infelizmente, a solução fornecida não funciona para um DataFrame do pandas.

piokuc
fonte

Respostas:

273

Você pode simplesmente usar DataFrame.fillnapara preencher os nanitens diretamente:

In [27]: df 
Out[27]: 
          A         B         C
0 -0.166919  0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3       NaN -2.027325  1.533582
4       NaN       NaN  0.461821
5 -0.788073       NaN       NaN
6 -0.916080 -0.612343       NaN
7 -0.887858  1.033826       NaN
8  1.948430  1.025011 -2.982224
9  0.019698 -0.795876 -0.046431

In [28]: df.mean()
Out[28]: 
A   -0.151121
B   -0.231291
C   -0.530307
dtype: float64

In [29]: df.fillna(df.mean())
Out[29]: 
          A         B         C
0 -0.166919  0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3 -0.151121 -2.027325  1.533582
4 -0.151121 -0.231291  0.461821
5 -0.788073 -0.231291 -0.530307
6 -0.916080 -0.612343 -0.530307
7 -0.887858  1.033826 -0.530307
8  1.948430  1.025011 -2.982224
9  0.019698 -0.795876 -0.046431

A doutrina de fillnadiz que valuedeveria ser um escalar ou um ditado, no entanto, parece funcionar também com um Series. Se você quiser passar um ditado, você pode usar df.mean().to_dict().

bmu
fonte
10
df.fillna(df.mean())retornará o novo quadro de dados, portanto você precisará escrever df=df.fillna(df.mean())para mantê-lo.
Yannis
Alguma idéia de por que eu posso estar recebendo a quantia errada imputada para a média usando isso?
22418 bernando_vialli
25
Em vez de df=df.fillna(df.mean())você também poderia usardf.fillna(df.mean(), inplace=True)
Anderson Pimentel
19
CUIDADO: se você quiser usar isso para Machine Learning / Data Science: do ponto de vista de Data Science, é errado primeiro substituir NA e depois dividir em treinar e testar ... É necessário primeiro dividir em treinar e testar e substituir NA por significa treinar e, em seguida, aplique esse modelo de pré-processamento com estado para testar, veja a resposta que envolve o sklearn abaixo!
Fabian Werner
1
@ amalik2205 porque, caso contrário, você está vazando informações do conjunto de testes para o conjunto de treinamento! Imagine o seguinte: temos 100 linhas de dados e consideramos a coluna x. As primeiras 99 entradas de x são NA. Queremos dividir a linha 100 como um conjunto de testes. Vamos supor que a linha 100 tenha o valor 20 na coluna x. Em seguida, você substituirá todas as entradas no conjunto de treinamento na coluna x por 20, um valor vindo 100% do conjunto de teste. Portanto, a avaliação pode enganá-lo!
Fabian Werner
51

Experimentar:

sub2['income'].fillna((sub2['income'].mean()), inplace=True)
Ammar Shigri
fonte
27
In [16]: df = DataFrame(np.random.randn(10,3))

In [17]: df.iloc[3:5,0] = np.nan

In [18]: df.iloc[4:6,1] = np.nan

In [19]: df.iloc[5:8,2] = np.nan

In [20]: df
Out[20]: 
          0         1         2
0  1.148272  0.227366 -2.368136
1 -0.820823  1.071471 -0.784713
2  0.157913  0.602857  0.665034
3       NaN -0.985188 -0.324136
4       NaN       NaN  0.238512
5  0.769657       NaN       NaN
6  0.141951  0.326064       NaN
7 -1.694475 -0.523440       NaN
8  0.352556 -0.551487 -1.639298
9 -2.067324 -0.492617 -1.675794

In [22]: df.mean()
Out[22]: 
0   -0.251534
1   -0.040622
2   -0.841219
dtype: float64

Aplique por coluna a média dessas colunas e preencha

In [23]: df.apply(lambda x: x.fillna(x.mean()),axis=0)
Out[23]: 
          0         1         2
0  1.148272  0.227366 -2.368136
1 -0.820823  1.071471 -0.784713
2  0.157913  0.602857  0.665034
3 -0.251534 -0.985188 -0.324136
4 -0.251534 -0.040622  0.238512
5  0.769657 -0.040622 -0.841219
6  0.141951  0.326064 -0.841219
7 -1.694475 -0.523440 -0.841219
8  0.352556 -0.551487 -1.639298
9 -2.067324 -0.492617 -1.675794
Jeff
fonte
4
Não sei por que, mas o df.fillna (df.mean ()) não funcionou, apenas sua versão com apply. Python 3
Rocketq
12
# To read data from csv file
Dataset = pd.read_csv('Data.csv')

X = Dataset.iloc[:, :-1].values

# To calculate mean use imputer class
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
imputer = imputer.fit(X[:, 1:3])
X[:, 1:3] = imputer.transform(X[:, 1:3])
Roshan jha
fonte
Qual é a vantagem de tudo isso sobre as alternativas mais simples?
AMC
@Roshan Jha É sempre melhor explicar a lógica. Existem várias maneiras de executar a mesma tarefa no R & Python. No entanto, se você está sugerindo algo diferente, você pode apontar algumas vantagens de fazê-lo
Dr. Nisha Arora
10

Se você deseja imputar valores ausentes com média e deseja ir coluna por coluna, isso só imputará a média dessa coluna. Isso pode ser um pouco mais legível.

sub2['income'] = sub2['income'].fillna((sub2['income'].mean()))
Pranay Aryal
fonte
3
Por favor, forneça uma explicação de como isso resolve o problema.
Gurwinder Singh
10

Use diretamente df.fillna(df.mean())para preencher todo o valor nulo com média

Se você desejar preencher um valor nulo com a média dessa coluna, poderá usar este

suponha que x=df['Item_Weight']aqui Item_Weightesteja o nome da coluna

aqui estamos atribuindo (preencha valores nulos de x com média de x em x)

df['Item_Weight'] = df['Item_Weight'].fillna((df['Item_Weight'].mean()))

Se você deseja preencher o valor nulo com alguma string, use

aqui Outlet_sizeestá o nome da coluna

df.Outlet_Size = df.Outlet_Size.fillna('Missing')
Sunny Barnwal
fonte
9

Outra opção além das acima é:

df = df.groupby(df.columns, axis = 1).transform(lambda x: x.fillna(x.mean()))

É menos elegante que as respostas anteriores para média, mas pode ser mais curto se você desejar substituir nulos por alguma outra função de coluna.

guibor
fonte
7

Pandas: Como substituir os nanvalores de NaN ( ) pela média (média), mediana ou outras estatísticas de uma coluna

Digamos que seu DataFrame seja dfe você tem uma coluna chamada nr_items. Isto é: df['nr_items']

Se você deseja substituir os NaNvalores da sua coluna df['nr_items']pela média da coluna :

Use o método .fillna():

mean_value=df['nr_items'].mean()
df['nr_item_ave']=df['nr_items'].fillna(mean_value)

Eu criei uma nova dfcoluna chamada nr_item_avepara armazenar a nova coluna com os NaNvalores substituídos pelo meanvalor da coluna.

Você deve ter cuidado ao usar o mean. Se você tiver discrepâncias, é mais recomendável usar omedian

pink.slash
fonte
0

usando a classe de pré-processamento da biblioteca sklearn

from sklearn.impute import SimpleImputer
missingvalues = SimpleImputer(missing_values = np.nan, strategy = 'mean', axis = 0)
missingvalues = missingvalues.fit(x[:,1:3])
x[:,1:3] = missingvalues.transform(x[:,1:3])

Nota: Na versão recente, missing_valuesaltere o valor do parâmetro para np.nandeNaN

Shrikant Chaudhari
fonte