繁体   English   中英

为什么更改一个np.nan值会更改熊猫数据框中的所有nan值?

[英]Why does changing one `np.nan` value change all of the nan values in pandas dataframe?

当我在整个DataFrame中更改一个值时,它也会更改其他值。 比较方案1和方案2:

方案1:在这里请注意,我只有NaNfloat(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_numinfo_num dtype='S3' (字符串)。 在第二个中,它是dtype=object ,是整数, nan (一个浮点数)和字符串(和一个None )的混合。

在数据框中,我看到一个打印为“ nan”的东西,另一个打印为“ None和“ NaN ”。 看起来fillna对待NoneNaN相同,但是忽略字符串'nan'。

fillna的文档

使用指定的方法填充NA / NaN值

Pandas NaNnp.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM