Как заменить каждый NaN в столбце различными случайными значениями с помощью панд?

В последнее время я играл с пандами, и теперь я пытался заменить значение NaN внутри фрейма данных другим случайным значением нормального распределения.

Предполагая, что у меня есть этот файл CSV без заголовка

      0
0    343
1    483
2    101
3    NaN
4    NaN
5    NaN

Мой ожидаемый результат должен быть примерно таким

       0
0     343
1     483
2     101
3     randomnumber1
4     randomnumber2
5     randomnumber3

Но вместо этого я получил следующее:

       0
0     343
1     483
2     101
3     randomnumber1
4     randomnumber1
5     randomnumber1    # all NaN filled with same number

Мой код пока

import numpy as np
import pandas as pd

df = pd.read_csv("testfile.csv", header=None)
mu, sigma = df.mean(), df.std()
norm_dist = np.random.normal(mu, sigma, 1)
for i in norm_dist:
    print df.fillna(i)

Я думаю, чтобы получить номер строки NaN из кадра данных, и заменить число 1 в np.random.normal(mu, sigma, 1) с общим количеством строк NaN, поэтому каждый NaN может иметь различное значение.

Но я хочу спросить, есть ли другой простой способ сделать это?

Спасибо за вашу помощь и предложение.

3 ответа

Решение

Вот один из способов работы с базовыми данными массива:

def fillNaN_with_unifrand(df):
    a = df.values
    m = np.isnan(a) # mask of NaNs
    mu, sigma = df.mean(), df.std()
    a[m] = np.random.normal(mu, sigma, size=m.sum())
    return df

По сути, мы генерируем все случайные числа за один раз с количеством NaN, используя параметр размера сnp.random.normal и назначая их за один раз с маской NaNs снова.

Пробный прогон -

In [435]: df
Out[435]: 
       0
0  343.0
1  483.0
2  101.0
3    NaN
4    NaN
5    NaN

In [436]: fillNaN_with_unifrand(df)
Out[436]: 
            0
0  343.000000
1  483.000000
2  101.000000
3  138.586483
4  223.454469
5  204.464514

Простое вложение случайных значений вместо отсутствующих значений в столбце DataFrame pandas.

mean = df['column'].mean()
std = df['column'].std()

def fill_missing_from_Gaussian(column_val):
    if np.isnan(column_val) == True: 
        column_val = np.random.normal(mean, std, 1)
    else:
         column_val = column_val
return column_val

Теперь просто примените вышеуказанный метод к столбцу с пропущенными значениями.

df['column'] = df['column'].apply(fill_missing_from_Gaussian) 

Я думаю, что вам нужно:

mu, sigma = df.mean(), df.std()
#get mask of NaNs
a = df[0].isnull()
#get random values by sum ot Trues, processes like 1
norm_dist = np.random.normal(mu, sigma, a.sum())
print (norm_dist)
[ 184.90581318  364.89367364  181.46335348]
#assign values by mask
df.loc[a, 0] = norm_dist
print (df)

            0
0  343.000000
1  483.000000
2  101.000000
3  184.905813
4  364.893674
5  181.463353
Другие вопросы по тегам