用随机值替换数据框中的NaN值。

12

我有一个包含NaN值的数据框(data_train),以下是一个示例:

republican                n                          y   
republican                n                          NaN   
democrat                 NaN                         n
democrat                  n                          y   

我希望用一些随机值,比如 ,来替换所有的NaN。

republican                n                           y   
republican                n                          rnd2
democrat                 rnd1                         n
democrat                  n                           y   

我该如何做。

我尝试了以下方法,但没有成功:

df_rand = pd.DataFrame(np.random.randn(data_train.shape[0],data_train.shape[1]))
data_train[pd.isnull(data_train)] = dfrand[pd.isnull(data_train)]

当我对一个包含随机数字数据的数据框执行上述操作时,上述脚本可以正常工作。


1
你的代码对我来说是有效的,但你有一个小错误:data_train[pd.isnull(data_train)] = df_rand[pd.isnull(data_train)] - EdChum
嗨,EdChum,是的,我知道打错了,那只是复制粘贴的错误。不管怎样,这段代码对我仍然不起作用...如果数据框(data_train)的列名和数据框(df_train)的列名不同,会有影响吗? - Sam
没错,它奏效了,两个数据框的列名似乎应该相同...谢谢。 - Sam
10个回答

7
如果您想将DF中的所有NaN替换为列表中的随机值,可以按以下方式操作:
import numpy as np

df.applymap(lambda l: l if not np.isnan(l) else np.random.choice([1, 3]))

6
您可以使用pandas update 命令,如下所示:

1)生成一个与原始数据框具有相同列和索引的随机数据框:

import numpy as np; import pandas as pd
M = len(df.index)
N = len(df.columns)
ran = pd.DataFrame(np.random.randn(M,N), columns=df.columns, index=df.index)

2) 然后使用update,这样df中的NaN值将被生成的随机值替换

df.update(ran)

在上面的示例中,我使用了标准正态分布的值,但您也可以使用从原始DataFrame随机选择的值:
import numpy as np; import pandas as pd

M = len(df.index)
N = len(df.columns)

val = np.ravel(df.values)
val = val[~np.isnan(val)]
val = np.random.choice(val, size=(M,N))
ran = pd.DataFrame(val, columns=df.columns, index=df.index)

df.update(ran)

2
据我所知,你的方法将所有值替换为随机值,而不仅仅是NaN值。 - Andrey

6

如果你使用fillna来填充NaN,那么随机生成器只会工作一次,并用相同的数字填充所有的N/As。

因此,请确保每次都生成并使用不同的随机数。例如对于这样的数据框:

          Date         A       B
0   2015-01-01       NaN     NaN
1   2015-01-02       NaN     NaN
2   2015-01-03       NaN     NaN
3   2015-01-04       NaN     NaN
4   2015-01-05       NaN     NaN
5   2015-01-06       NaN     NaN
6   2015-01-07       NaN     NaN
7   2015-01-08       NaN     NaN
8   2015-01-09       NaN     NaN
9   2015-01-10       NaN     NaN
10  2015-01-11       NaN     NaN
11  2015-01-12       NaN     NaN
12  2015-01-13       NaN     NaN
13  2015-01-14       NaN     NaN
14  2015-01-15       NaN     NaN
15  2015-01-16       NaN     NaN

我使用了以下代码来填充列A中的NaN:

import random
x['A'] = x['A'].apply(lambda v: random.random() * 1000)

这将会给我们带来类似于以下的结果:
          Date           A       B
0   2015-01-01   96.538211     NaN
1   2015-01-02  404.683392     NaN
2   2015-01-03  849.614253     NaN
3   2015-01-04  590.030660     NaN
4   2015-01-05  203.167519     NaN
5   2015-01-06  980.508258     NaN
6   2015-01-07  221.088002     NaN
7   2015-01-08  285.013762     NaN

原帖作者想要“用一些随机值替换所有NaN”。 您的解决方案将所有NaN替换为随机值。 - user582175
4
这可能不是一个好的解决方案,如果你想保留'A'列的原始数据,但这个方法也会改变那些原始数据。 - aksr

2
如果您想使用热卡技术替换列中的 NaN,请按以下方式进行:

如果要使用热卡技术替换列中的 NaN,则可以采用以下方法:

def hot_deck(dataframe) :
    dataframe = dataframe.fillna(0)
    for col in dataframe.columns :
        assert (dataframe[col].dtype == np.float64) | (dataframe[col].dtype == np.int64)
        liste_sample = dataframe[dataframe[col] != 0][col].unique()
        dataframe[col] = dataframe.apply(lambda row : random.choice(liste_sample) if row[col] == 0 else row[col],axis=1)
    return dataframe

如果你希望每次迭代时用一个新的随机值来替换NaN,可以像这样做。只需要确定你的随机选择的最大值即可。
def hot_deck(dataframe,max_value) :
    dataframe = dataframe.fillna(0)
    for col in dataframe.columns :
        assert (dataframe[col].dtype == np.float64) | (dataframe[col].dtype == np.int64)
        liste_sample = random.sample(range(max_value),dataframe.isnull().sum())
        dataframe[col] = dataframe.apply(lambda row : random.choice(liste_sample) if row[col] == 0 else row[col],axis=1)
    return dataframe

1
你可以使用#波浪号运算符随机填充值。
df['column'].dropna()
df["column"].fillna(np.random.choice(df['column'][~df['column'].isna()]),inplace = True)

0

试试我的代码。我将之前的回答组合成了一个可工作的示例:

  M = len(data_train.index)
  N = len(data_train.columns)
  df_rand = pd.DataFrame(np.random.randn(M,N), columns=data_train.columns, index=data_train.index)
  data_train[pd.isnull(data_train)] = df_rand[pd.isnull(data_train)]

它比使用 apply_map 更快。


0

在循环中使用fillna()函数,并将'limit'属性设置为1,可以帮助用不同的随机值替换nan。

import random
while(Series.isnull().sum()!=0):
    Series.fillna(random.uniform(0,100),inplace=True,limit=1)

0
如果你说的“随机”实际上是指需要唯一值,那么这个快速解决方案适用于各种进一步的快速修改。
mask = df[col].isnull()
df[col][mask] = df[col][mask].index#.astype(str).str.etc...

0
根据离散列分布替换NaN值。
import pandas as pd
import numpy as np

def discrete_column_resampling(df, column_names):
        for column in column_names:
            value_counts = df[column].value_counts()
            counts = np.array(value_counts.values.tolist())
            probabilities = counts / np.sum(counts)
            values = value_counts.index.tolist()
            df[column] = df[column].apply(lambda l: l if not pd.isna(l) else \
                np.random.choice(values, p=probabilities))

-1
只需这样使用fillna
import random
data_train.fillna(random.random())

10
嗨,farhawa,上面的代码会用相同的随机数填充每个NaN值,但我需要对于每个NaN值都填充一个不同的随机数。 - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接