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

如何使用连接来填充列的缺失值 - Python Pandas?

Python Pandas - 用前一列的值向前填充整行