Pandas - 使用多个值填充 NaN
Posted
技术标签:
【中文标题】Pandas - 使用多个值填充 NaN【英文标题】:Pandas - Fill NaN using multiple values 【发布时间】:2019-12-26 10:00:10 【问题描述】:我有一个包含大约 16000 个 NaN 值的列(我们称之为 X 列)。该列有两个可能的值,1 或 0(就像二进制一样)
我想在 X 列中填充 NaN 值,但我不想为所有 NaN 条目使用单个值。
比如说;我想用 '1' 填充 50% 的 NaN 值,用 '0' 填充另外 50% 的值。
我已阅读“fillna()”文档,但没有找到任何可以满足此功能的相关信息。
我真的不知道如何解决这个问题,所以我没有尝试过任何事情。
df['Column_x'] = df['Column_x'].fillna(df['Column_x'].mode()[0], inplace= True)
但这会用列的模式填充我的数据框“df”的 X 列中的所有 NaN 值,我想用一个值填充 50%,用不同的值填充其他 50%。
由于我还没有尝试过任何东西,我无法展示或描述任何实际结果。
我可以说的是,预期的结果将类似于将 x 列的 8000 个 NaN 值替换为 '1' 和另一个 8000 替换为 '0' 。
视觉结果类似于;
在处理 NaN 之前
Index Column_x
0 0.0
1 0.0
2 0.0
3 0.0
4 0.0
5 0.0
6 1.0
7 1.0
8 1.0
9 1.0
10 1.0
11 1.0
12 NaN
13 NaN
14 NaN
15 NaN
16 NaN
17 NaN
18 NaN
19 NaN
处理 NaN 后
Index Column_x
0 0.0
1 0.0
2 0.0
3 0.0
4 0.0
5 0.0
6 1.0
7 1.0
8 1.0
9 1.0
10 1.0
11 1.0
12 0.0
13 0.0
14 0.0
15 0.0
16 1.0
17 1.0
18 1.0
19 1.0
【问题讨论】:
是否应该填写 0 或 1 是否有规则?如果它应该是随机的,您可以尝试用 0 到 1 之间的随机浮点数填充 NaN 值,然后将它们四舍五入。 NaN 是否必须具有精确(或尽可能接近)50-50% 的 1 和 0? @Carsten 它必须是 0 或 1,因为我正在处理只能有 1 或 0 的列中的缺失数据。50-50 的比率对于保持列平衡非常重要表格(数据可能会在不尊重比率的情况下出现偏差)你能告诉我如何用随机方式填充 NaN,就像你说的那样? @Chris 如果我在填充 NaN 时改变 50-50 的比例,它可能会扭曲数据。这就是我坚持的原因。但如果您有任何可以帮助我的方法,请分享 【参考方案1】:使用slicing columns
并填写值
isnull()
- 函数检测给定系列对象中的缺失值
例如
import pandas as pd
df = pd.DataFrame('Column_y': pd.Series(range(9), index=['a', 'b', 'c','d','e','f','g','h','i']),
'Column_x': pd.Series(range(1), index=['a']))
print(df)
# get list of index series which have NaN Column_x value
idx = df['Column_x'].index[df['Column_x'].isnull()]
total_nan_len = len(idx)
first_nan = total_nan_len//2
# fill first 50% of 1
df.loc[idx[0:first_nan], 'Column_x'] = 1
# fill last 50% of 0
df.loc[idx[first_nan:total_nan_len], 'Column_x'] = 0
print(df)
O/P:
数据帧之前
Column_y Column_x
a 0 0.0
b 1 NaN
c 2 NaN
d 3 NaN
e 4 NaN
f 5 NaN
g 6 NaN
h 7 NaN
i 8 NaN
数据帧之后
Column_y Column_x
a 0 0.0
b 1 1.0
c 2 1.0
d 3 1.0
e 4 1.0
f 5 0.0
g 6 0.0
h 7 0.0
i 8 0.0
【讨论】:
【参考方案2】:您可以使用random.choices
及其权重参数来确保分布保持不变。我在这里用 numpy 模拟了一个 NaN 列,并获得了所需替换的确切长度。这种方法也可以用于具有两个以上类别和更复杂分布的列。
import pandas as pd
import numpy as np
import random
df = pd.DataFrame('col1': range(16000))
df['col2'] = np.nan
nans = df['col2'].isna()
length = sum(nans)
replacement = random.choices([0, 1], weights=[.5, .5], k=length)
df.loc[nans,'col2'] = replacement
print(df.describe())
'''
Out:
col1 col2
count 16000.000000 16000.000000
mean 7999.500000 0.507625
std 4618.946489 0.499957
min 0.000000 0.000000
25% 3999.750000 0.000000
50% 7999.500000 1.000000
75% 11999.250000 1.000000
max 15999.000000 1.000000
'''
【讨论】:
嘿伊万!我看到您的回答将允许处理更复杂的案件。感谢您为解决方案的范围增加了一个新维度。【参考方案3】:使用pandas.Series.sample
:
mask = df['Column_x'].isna()
ind = df['Column_x'].loc[mask].sample(frac=0.5).index
df.loc[ind, 'Column_x'] = 1
df['Column_x'] = df['Column_x'].fillna(0)
print(df)
输出:
Index Column_x
0 0 0.0
1 1 0.0
2 2 0.0
3 3 0.0
4 4 0.0
5 5 0.0
6 6 1.0
7 7 1.0
8 8 1.0
9 9 1.0
10 10 1.0
11 11 1.0
12 12 1.0
13 13 0.0
14 14 1.0
15 15 0.0
16 16 0.0
17 17 1.0
18 18 1.0
19 19 0.0
【讨论】:
谢谢!这完全符合我的需要以上是关于Pandas - 使用多个值填充 NaN的主要内容,如果未能解决你的问题,请参考以下文章
06 pandas DataFrame - 数据过滤、NaN处理、统计方法
Pandas 用 NaN 值填充列中的单元格,从行中的其他单元格中获取值
Pandas 均值数据透视表包含 NaN 值,即使在聚合之前填充了数据
在 Pandas 中处理 Nulls – 在一列中使用过滤值来填充另外两列中的 nan