gpt4 book ai didi

python - 每列中的变量 fillna()

转载 作者:行者123 更新时间:2023-11-28 18:57:49 25 4
gpt4 key购买 nike

对于初学者,这里有一些符合我的问题的人工数据:

df = pd.DataFrame(np.random.randint(0, 100, size=(vsize, 10)), 
columns = ["col_{}".format(x) for x in range(10)],
index = range(0, vsize * 3, 3))

df_2 = pd.DataFrame(np.random.randint(0,100,size=(vsize, 10)),
columns = ["col_{}".format(x) for x in range(10, 20, 1)],
index = range(0, vsize * 2, 2))

df = df.merge(df_2, left_index = True, right_index = True, how = 'outer')

df_tar = pd.DataFrame({"tar_1": [np.random.randint(0, 2) for x in range(vsize * 3)],
"tar_2": [np.random.randint(0, 4) for x in range(vsize * 3)],
"tar_3": [np.random.randint(0, 8) for x in range(vsize * 3)],
"tar_4": [np.random.randint(0, 16) for x in range(vsize * 3)]})

df = df.merge(df_tar, left_index = True, right_index = True, how = 'inner')

现在,我想在每列中填充 NaN 值,在每列中使用非 NaN 值的 MEDIAN 值,但向该列中每个填充的 NaN 添加噪声。应该为该列中属于同一类的值计算 MEDIAN 值,如首先在列 tar_4 中标记的那样。然后,如果列中存在任何 NaN(因为列中的某些值都在 tar_4 类中,只有 NaN,所以无法计算 MEDIAN),在更新的列上重复相同的操作(一些 NaN 已经填充)来自 tar_4 操作),但具有相对于 tar_3 列属于同一类的值。然后是 tar_2 和 tar_1。

我想象的方式如下:

  • col_1 特征,例如6 个非 Nan 和 4 个 NaN 值:[1, 2, NaN, 4, NaN, 12, 5, NaN, 1, NaN]
  • 只有值 [1, 2, NaN, 4, NaN] 属于 tar_4 中的同一类(例如类 1),因此它们被插入 NaN 填充:
    • 索引 [2] 处的 NaN 值填充有 MEDIAN (=2) + random(-3, 3) * col_1 中分布的标准误差,例如2 + (1 * 1.24)
    • 索引 [4] 处的 NaN 值用 MEDIAN (=2) + random(-3, 3) * col_1 中的标准分布误差填充,例如2 + (-2 * 1.24)
  • 现在 col_1 有以下 8 个非 NaN 值和 2 个 NaN 值:[1, 2, 1.24, 4, -0.48, 12, 5, NaN, 1, NaN]
  • 列 col_1 仍然具有一些 NaN 值,因此应用基于 tar_3 列中公共(public)类的分组:
    • 在 [1, 2, 1.24, 4, -0.48, 12, 5, NaN, 1, NaN] 中,值 [1, 2, 1.24, 4, -0.48, 12, 5, NaN] 在现在同一个类(class),所以他们得到处理:
    • 索引 [7] 处的 NaN 值被分配为索引 [0-6] (=2) + random(-3, 3) * std error 中值的 MEDIAN,例如2 + 2 * 3.86
  • 现在 col_1 有 9 个非 NaN 值和 1 个 NaN 值:[1, 2, 1.24, 4, -0.48, 12, 5, 9.72, 1, NaN]
    • col_1 中的所有值都属于基于 tar_2 列的同一类,因此索引 [9] 处的 NaN 值使用相同的逻辑进行处理,如上所述,并以值 2 * (-1 * 4.05)
  • col_1 现在只有非 NaN 值:[1, 2, 1.24, 4, -0.48, 12, 5, 9.72, 1, -6.09],不需要基于 tar_1 进行 NaN 填充推送专栏。

相同的逻辑贯穿其余的列。

因此,预期输出:填充了 NaN 值的 DataFrame,在基于列 tar_4 - tar_1 的类粒度级别递减的每一列中。

我已经有了一个代码,它实现了这一点,感谢@Quang Hoang:

def min_max_check(col):
if ((df[col].dropna() >= 0) & (df[col].dropna() <= 1.0)).all():
return medians[col]
elif (df[col].dropna() >= 0).all():
return medians[col] + round(np.random.randint(low = 0, high = 3) * stds[col], 2)
else:
return medians[col] + round(np.random.randint(low = -3, high = 3) * stds[col], 2)


tar_list = ['tar_4', 'tar_3', 'tar_2', 'tar_1']
cols = [col for col in df.columns if col not in tar_list]
# since your dataframe may not have continuous index
idx = df.index

for tar in tar_list:
medians = df[cols].groupby(by = df[tar]).agg('median')
std = df[cols].groupby(by = df[tar]).agg(np.std)
df.set_index(tar, inplace=True)
for col in cols:
df[col] = df[col].fillna(min_max_check(col))
df.reset_index(inplace=True)

df.index = idx

但是,这只会在每个粒度级别使用相同的 MEDIAN 值 + 噪声填充 NaN 值。如何增强此代码以便为每个 NaN 值生成不同的填充值,例如tar_4、ta​​r_3、tar_2 和 tar_1 级别?

最佳答案

一个快速的解决方案是将每一行的 min_max_check 修改为 get_noise:

def gen_noise(col):
num_row = len(df)

# generate noise of the same height as our dataset
# notice the size argument in randint
if ((df[col].dropna() >= 0) & (df[col].dropna() <= 1.0)).all():
noise = 0
elif (df[col].dropna() >= 0).all():
noise = np.random.randint(low = 0,
high = 3,
size=num_row)
else:
noise = np.random.randint(low = -3,
high = 3,
size=num_row)

# multiplication with isna() forces those at non-null values in df[col] to be 0
return noise * df[col].isna()

然后:

df.set_index(tar, inplace=True)

for col in cols[:1]:
noise = gen_noise(col)
df[col] = (df[col].fillna(medians[col])
.add(noise.mul(stds[col]).values)
)

df.reset_index(inplace=True)

注意:您可以进一步修改代码,生成与 mediansstds 大小相同的 noise_df,一些像这样

for tar in tar_list:
medians = df[cols].groupby(df[tar]).agg('median')
stds = df[cols].groupby(df[tar]).agg('std')

# generate noise_df here
medians = medians + round(noise_df*std, 2)

df.set_index(tar, inplace=True)

for col in cols[:1]:
df[col] = df[col].fillna(medians[col])

df.reset_index(inplace=True)

df.index = idx

关于python - 每列中的变量 fillna(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56178297/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com