当我在整个DataFrame中更改一个值时,它会更改其他值。比较方案1和方案2:
情况1:请注意,我float(np.nan)
s只有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!?!
即使我只使用“无”填充其中一个NaN值,其他float(np.nan)
也会填入0.0
,就好像它们也是NaN
一样。
为什么NaN
之间存在某种关系?
答案 0 :(得分:1)
第一个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
数组必须统一元素;使用整数,整数,字符串和字符串,只能使用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
我不确定pandas是如何在内部存储的,但是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
,则所有数字都为float(nan
是一种浮点数)。前2列保持整数。最后一个是字符串和nan
的混合。
但是dtypes
表明pandas正在使用结构化数组,每列都是field
,并且具有相关的dtype。
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