![](/img/trans.png)
[英]Use None instead of np.nan for null values in pandas DataFrame
[英]Why does changing one `np.nan` value change all of the nan values in pandas dataframe?
当我在整个DataFrame中更改一个值时,它也会更改其他值。 比较方案1和方案2:
方案1:在这里请注意,我只有NaN
的float(np.nan)
值
info_num = np.array([[random.randint(0,9) for x in range(4)]+['ui'],
[random.randint(0,8) for x in range(3)]+[float(np.nan)]+['g'],
[random.randint(0,7) for x in range(2)]+[float(np.nan)]+[90]+[float(np.nan)],
[random.randint(0,9) for x in range(4)]+['q'],
[random.randint(0,9) for x in range(4)]+['w']])
result_df = pd.DataFrame(data=info_num, columns=['G','Bd', 'O', 'P', 'keys'])
result_df = result_df.fillna(0.0) # does NOT fill in NaNs
方案1的结果只是一个没有填写NaN的数据框。
方案2:在这里请注意,我在一个位置上只有None
值
info_num = np.array([[random.randint(0,9) for x in range(4)]+['ui'],
[random.randint(0,8) for x in range(3)]+[None]+['g'],
[random.randint(0,7) for x in range(2)]+[float(np.nan)]+[90]+[float(np.nan)],
[random.randint(0,9) for x in range(4)]+['q'],
[random.randint(0,9) for x in range(4)]+['w']])
result_df = pd.DataFrame(data=info_num, columns=['G','Bd', 'O', 'P', 'keys'])
result_df = result_df.fillna(0.0) # this works!?!
即使我只用None填充一个NaN值,另一个float(np.nan)
用0.0
填充,就好像它们也是NaN
。
为什么NaN
之间存在某种关系?
第一个info_num
是info_num
dtype='S3'
(字符串)。 在第二个中,它是dtype=object
,是整数, nan
(一个浮点数)和字符串(和一个None
)的混合。
在数据框中,我看到一个打印为“ nan”的东西,另一个打印为“ None
和“ NaN
”。 看起来fillna
对待None
和NaN
相同,但是忽略字符串'nan'。
fillna
的文档
使用指定的方法填充NA / NaN值
Pandas NaN
与np.nan
相同。
fillna
使用pd.isnull
确定将0.0
值放在何处。
def isnull(obj):
"""Detect missing values (NaN in numeric arrays, None/NaN in object arrays)
对于第二种情况:
In [116]: pd.isnull(result_df)
Out[116]:
G Bd O P keys
0 False False False False False
1 False False False True False
2 False False True False True
3 False False False False False
4 False False False False False
(对于第一个,字符串,大小写,全部为False
)。
In [121]: info_num0
Out[121]:
array([['4', '8', '5', '6', 'ui'],
['1', '5', '6', 'nan', 'g'],
['6', '1', 'nan', '90', 'nan'],
['5', '2', '8', '4', 'q'],
['1', '6', '4', '3', 'w']],
dtype='<U3')
In [122]: info_num
Out[122]:
array([[1, 8, 3, 0, 'ui'],
[1, 5, 1, None, 'g'],
[0, 2, nan, 90, nan],
[7, 7, 1, 4, 'q'],
[3, 7, 0, 3, 'w']], dtype=object)
np.nan
已经float
:
In [125]: type(np.nan)
Out[125]: float
如果将dtype=object
添加到初始数组定义中,则将获得与使用None
相同的效果:
In [140]: np.array([[random.randint(0,9) for x in range(4)]+['ui'],
[random.randint(0,8) for x in range(3)]+[np.nan]+['g'],
[random.randint(0,7) for x in range(2)]+[np.nan]+[90]+[np.nan],
[random.randint(0,9) for x in range(4)]+['q'],
[random.randint(0,9) for x in range(4)]+['w']],dtype=object)
Out[140]:
array([[6, 7, 8, 1, 'ui'],
[5, 2, 5, nan, 'g'],
[3, 0, nan, 90, nan],
[5, 2, 1, 3, 'q'],
[1, 7, 7, 2, 'w']], dtype=object)
更好的是,将初始数据创建为列表列表,而不是数组。 numpy
数组必须统一元素; 混合使用ints,nan和字符串,您只能通过dtype=object
获得它。 但这仅是列表周围的数组包装器而已。 Python列表已经允许这种多样性。
In [141]: alist = [[random.randint(0,9) for x in range(4)]+['ui'],
[random.randint(0,8) for x in range(3)]+[np.nan]+['g'],
[random.randint(0,7) for x in range(2)]+[np.nan]+[90]+[np.nan],
[random.randint(0,9) for x in range(4)]+['q'],
[random.randint(0,9) for x in range(4)]+['w']]
In [142]: alist
Out[142]:
[[4, 0, 2, 6, 'ui'],
[3, 3, 3, nan, 'g'],
[3, 5, nan, 90, nan],
[4, 0, 6, 7, 'q'],
[0, 8, 3, 8, 'w']]
In [143]: result_df1 = pd.DataFrame(data=alist, columns=['G','Bd', 'O', 'P', 'keys'])
In [144]: result_df1
Out[144]:
G Bd O P keys
0 4 0 2 6 ui
1 3 3 3 NaN g
2 3 5 NaN 90 NaN
3 4 0 6 7 q
4 0 8 3 8 w
我不确定熊猫如何在内部存储它,但是result_df1.values
确实返回一个对象数组。
In [146]: result_df1.values
Out[146]:
array([[4, 0, 2.0, 6.0, 'ui'],
[3, 3, 3.0, nan, 'g'],
[3, 5, nan, 90.0, nan],
[4, 0, 6.0, 7.0, 'q'],
[0, 8, 3.0, 8.0, 'w']], dtype=object)
因此,如果一列具有nan
,则所有数字均为浮点数( nan
是一种浮点数)。 前两列保持为整数。 最后是字符串和那个nan
的混合。
但是dtypes
建议熊猫使用结构化数组,每列都是具有相关dtype的field
。
In [147]: result_df1.dtypes
Out[147]:
G int64
Bd int64
O float64
P float64
keys object
dtype: object
等效的numpy
dtype将是:
dt = np.dtype([('G',np.int64),('Bd',np.int64),('O',np.float64),('P',np.float64), ('keys',object)])
我们可以使用此dtype创建结构化数组。 我必须将列表列表转换为元组列表(结构化记录):
X = np.array([tuple(x) for x in alist],dt)
生产:
array([(4, 0, 2.0, 6.0, 'ui'),
(3, 3, 3.0, nan, 'g'),
(3, 5, nan, 90.0, nan),
(4, 0, 6.0, 7.0, 'q'),
(0, 8, 3.0, 8.0, 'w')],
dtype=[('G', '<i8'), ('Bd', '<i8'), ('O', '<f8'), ('P', '<f8'), ('keys', 'O')])
可以直接通过以下方式进入熊猫:
In [162]: pd.DataFrame(data=X)
Out[162]:
G Bd O P keys
0 4 0 2 6 ui
1 3 3 3 NaN g
2 3 5 NaN 90 NaN
3 4 0 6 7 q
4 0 8 3 8 w
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.