Python 对于数据帧中的每个列和单元格,使用该列中的随机值填充NaN/Nulls

Python 对于数据帧中的每个列和单元格,使用该列中的随机值填充NaN/Nulls,python,pandas,Python,Pandas,我试图通过对数据帧中的每一列和每一列中的每一个单元格进行随机采样(例如采样非NaN值),为该列填充NaN/null值。我现在正在做以下事情 for col in df: count = 0 while True: sample = df[col].sample(n=1) count += 1 if pd.notna(sample.item()): df[c

我试图通过对数据帧中的每一列和每一列中的每一个单元格进行随机采样(例如采样非NaN值),为该列填充NaN/null值。我现在正在做以下事情

   for col in df:
        count = 0
        while True:
            sample = df[col].sample(n=1)
            count += 1
            if pd.notna(sample.item()):
                df[col].replace(sample, np.nan, inplace=True)
                break
            if count >= 100:
                break
这是不正确的,因为:

  • 它有这样一个技巧:尝试100次采样,希望在100次尝试中最终找到非NaN

  • 它将用样本填充单元格,而我希望为每个单元格分别随机采样一个值,例如,不存在任何歪斜

  • 在任何情况下,由于某种原因,它都不起作用,因此df像以前一样具有NAN


  • 注意:数据框同时包含数字和字符串

    您可以使用
    np.random.choice
    从一组值中生成样本:

    sample = np.random.choice(pop, size=len(df)-len(pop), replace=True)
    
    比如说,

    import numpy as np
    import pandas as pd
    
    arr = np.random.randint(10, size=(10,3)).astype(float)
    mask = np.random.randint(2, size=arr.shape, dtype=bool)
    arr[mask] = np.nan
    df = pd.DataFrame(arr)
    print(df)
    #      0    1    2
    # 0  8.0  NaN  0.0
    # 1  1.0  3.0  2.0
    # 2  NaN  NaN  NaN
    # 3  6.0  NaN  7.0
    # 4  NaN  8.0  5.0
    # 5  1.0  4.0  6.0
    # 6  NaN  NaN  NaN
    # 7  NaN  NaN  NaN
    # 8  8.0  NaN  NaN
    # 9  5.0  NaN  2.0
    
    for col in df:
        mask = pd.isnull(df[col])
        pop = df[col].dropna()
        if len(pop):
            sample = np.random.choice(pop, size=len(df)-len(pop), replace=True)
            df.loc[mask, col] = sample
    
    
    print(df)
    
    产生如下结果:

         0    1    2
    0  8.0  4.0  0.0
    1  1.0  3.0  2.0
    2  1.0  8.0  2.0
    3  6.0  3.0  7.0
    4  8.0  8.0  5.0
    5  1.0  4.0  6.0
    6  1.0  8.0  2.0
    7  8.0  4.0  6.0
    8  8.0  4.0  7.0
    9  5.0  3.0  2.0
    

    df[col]
    返回一个序列。修改此系列不保证 修改df本身。因此

    df[col].replace(sample, np.nan, inplace=True)
    
    修改由
    df[col]
    返回的序列,但无法修改
    df

    通常,要确保修改数据帧,请使用
    df.loc[…]=…

    或者
    df.iloc[…]=…
    或者生成一个新的数据帧并将其重新分配给
    df
    (例如
    df=new_-df
    ),或者生成一个新的值列并将其重新分配给一列(例如
    df[col]=values
    )。

    运行时,我在这一行得到“sample=np.random.choice(pop,size=len(df)-len(pop),replace=True)“我的df具有混合类型数据。它适用于混合类型数据吗?看起来应该是这样的,但只需记下
    value错误:如果
    len(pop)
    为0,则会出现一个必须为非空的
    。换句话说,该列没有非nan值。在这种情况下你希望发生什么?保留所有nan值或引发ValueError都是合理的可能性…混合数据类型不是问题,因为每个列都有一个共享的数据类型,并且我们正在分配具有相同数据类型的值。我更改了代码,如果该列没有非nan值,则只保留nan。