如何使用 pandas 将一列中的每个 NaN 替换为不同的随机值?
How to replace every NaN in a column with different random values using pandas?
我最近一直在玩 pandas,现在我尝试用正态分布的不同随机值替换数据框中的 NaN 值。
假设我有这个没有 header
的 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 行的数量,并将 np.random.normal(mu, sigma, 1)
中的数字 1 替换为 NaN 行的总数,因此每个 NaN 可能具有不同的值。
但是我想问一下有没有其他简单的方法可以做到这一点?
感谢您的帮助和建议。
我认为你需要:
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
这是处理底层数组数据的一种方法 -
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
本质上,我们使用 size param with np.random.normal
一次性生成所有随机数和 NaN 的计数,并再次使用 NaN 的掩码一次性分配它们。
样本运行-
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
用随机值代替 pandas DataFrame 列中的缺失值很简单。
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)
我最近一直在玩 pandas,现在我尝试用正态分布的不同随机值替换数据框中的 NaN 值。
假设我有这个没有 header
的 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 行的数量,并将 np.random.normal(mu, sigma, 1)
中的数字 1 替换为 NaN 行的总数,因此每个 NaN 可能具有不同的值。
但是我想问一下有没有其他简单的方法可以做到这一点?
感谢您的帮助和建议。
我认为你需要:
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
这是处理底层数组数据的一种方法 -
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
本质上,我们使用 size param with np.random.normal
一次性生成所有随机数和 NaN 的计数,并再次使用 NaN 的掩码一次性分配它们。
样本运行-
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
用随机值代替 pandas DataFrame 列中的缺失值很简单。
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)