numpy中的nan和inf
numpy中的nan和inf
- numpy中有两个特殊数值
nan 和 inf
一、nan和inf
1. nan
- nan全称为 not a number ,表示不是一个数字
- 对于
nan,任何数值(包括其本身)和它的比较都是false的结果,因为nan不等于任何值 - 什么时候数组中会出现nan:
- 当我们读取本地文件为float的时候,如果某些位置有缺失的数据,就会用nan代替
- 当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)
2. inf
-
inf ,全称为 infinity,表示无穷大的意思,分为
-inf 和 +inf(加号可以省略),分别表示正无穷大和负无穷大 -
对于
inf,任何有限数都比它小,因为inf是正无穷大的意思,对于-inf,任何有限数都大于它 -
什么时候数组中会出现inf:
- 当一个数字除以0,python中会直接报错,但是在numpy中结果是一个inf或者 -inf
3. 如何赋值为nan、inf
import numpy as np
t = np.nan
print(t)
print(type(t))
print('*'*30)
t1 = np.inf
print(t1)
print(type(t1))
nan
<class 'float'>
******************************
inf
<class 'float'>
- 因为numpy数组中的数值类型都是一致的,所以当我们想改变其中的值为nan或inf时,首先应该要知道nan、inf的数值类型到底属于哪种
- 从上面的代码可以看到,nan和inf都属于float类型,可以通过
numpy.nan 和 numpy.inf来对一个变量直接进行赋值,当对数组进行改值时,首先需要将数组的数值类型转换为float,即ndarray.astype('float')
二、nan的特性
- 两个nan是不相等的,利用这个特性,可以统计数组中nan的个数
- 无论何值,和nan进行计算时,其结果都为nan
1. 比较两个nan和两个inf
# 1. 两个nan是不相等的
print("nan==nan:", np.nan==np.nan)
print("nan!=nan:", np.nan!=np.nan)
"""
nan==nan: False
nan!=nan: True
"""
2. inf自身的比较
print(np.inf > np.inf)
print(np.inf < np.inf)
print(np.inf == np.inf)
print((-np.inf) > (-np.inf))
print((-np.inf) < (-np.inf))
print((-np.inf) == (-np.inf))
"""
False
False
True
False
False
True
"""
2. 统计数组中的非0元素个数
- 语法:
numpy.count_nonzero(数组)- 该方法虽然统计的是非0的个数,其实统计的是非假的个数,即非false的元素个数
- 在python中,0也是假
t = np.arange(24).reshape(4, 6)
t[:,0] = 0 # 将第一列变为0
print(t)
print(np.count_nonzero(t)) # 20
"""
[[ 0 1 2 3 4 5]
[ 0 7 8 9 10 11]
[ 0 13 14 15 16 17]
[ 0 19 20 21 22 23]]
20
"""
3. 将数组中的元素赋值为nan
- 前面我们提到,nan和inf都是float类型,所以要将数组中的元素变为nan,首先要确保数组的数值类型为float
t = np.arange(24).reshape(4, 6)
t[:,0] = 0 # 将第一列变为0
print(t)
print(np.count_nonzero(t)) # 20
print("*"*50)
t = t.astype('float') # 改变数组的数值类型为float
t[2,3] = np.nan # 将坐标(2,3)的值变为 nan
print(t)
"""
[[ 0 1 2 3 4 5]
[ 0 7 8 9 10 11]
[ 0 13 14 15 16 17]
[ 0 19 20 21 22 23]]
20
**************************************************
[[ 0. 1. 2. 3. 4. 5.]
[ 0. 7. 8. 9. 10. 11.]
[ 0. 13. 14. nan 16. 17.]
[ 0. 19. 20. 21. 22. 23.]]
"""
4. 统计数组中nan的个数
- 利用上面提到的两个nan不相等的特性,以及统计数组中非0个数的方法,即可统计出数组中nan的个数
- 也可以通过下面
isnan()的方法来比较后统计个数
t = np.arange(24).reshape(4, 6)
t[:,0] = 0 # 将第一列变为0
print(t)
print(np.count_nonzero(t)) # 20
print("*"*50)
t = t.astype('float') # 改变数组的数值类型为float
t[2,3] = np.nan # 将坐标(2,3)的值变为 nan
print(t)
print("*"*50)
t1 = t != t
print(t1)
print(np.count_nonzero(t1)) # 同 print(np.count_nonzero(t != t))
"""
[[ 0 1 2 3 4 5]
[ 0 7 8 9 10 11]
[ 0 13 14 15 16 17]
[ 0 19 20 21 22 23]]
20
**************************************************
[[ 0. 1. 2. 3. 4. 5.]
[ 0. 7. 8. 9. 10. 11.]
[ 0. 13. 14. nan 16. 17.]
[ 0. 19. 20. 21. 22. 23.]]
**************************************************
[[False False False False False False]
[False False False False False False]
[False False False True False False]
[False False False False False False]]
1
"""
5. 判断一个值是否为nan
- 语法:
numpy.isnan() - 用这个方法同样能得到上面
t!=t的结果
t = np.arange(24).reshape(4, 6)
t[:,0] = 0 # 将第一列变为0
print(t)
print(np.count_nonzero(t)) # 20
print("*"*50)
t = t.astype('float') # 改变数组的数值类型为float
t[2,3] = np.nan # 将坐标(2,3)的值变为 nan
print(t)
print("*"*50)
t1 = t != t
print(t1)
# print(np.count_nonzero(t1))
print(np.count_nonzero(t != t))
print("*"*50)
t2 = np.isnan(t) # 判断数组中每个元素的值是否是nan
print(t2)
print(np.count_nonzero(t2)) # 同 print(np.count_nonzero(np.isnan(t)))
"""
[[ 0 1 2 3 4 5]
[ 0 7 8 9 10 11]
[ 0 13 14 15 16 17]
[ 0 19 20 21 22 23]]
20
**************************************************
[[ 0. 1. 2. 3. 4. 5.]
[ 0. 7. 8. 9. 10. 11.]
[ 0. 13. 14. nan 16. 17.]
[ 0. 19. 20. 21. 22. 23.]]
**************************************************
[[False False False False False False]
[False False False False False False]
[False False False True False False]
[False False False False False False]]
1
**************************************************
[[False False False False False False]
[False False False False False False]
[False False False True False False]
[False False False False False False]]
1
"""
三、数组”约减“(聚合)操作中nan的影响
-
这里拿求和sum()方法来举例
-
由于无论何值,和nan进行运算时,其结果都为nan。此时,有两种办法,1将nan替换为其他值,2删除掉nan所在的行或列
-
在一组数据中单纯的把nan替换为0并不合适。全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行
-
示例
# nan缺失值填充均值
t1 = np.arange(12).reshape((3, 4)).astype("float")
print('t1')
print(t1.size) # 获取数组中所有的元素个数,相当于ndarray.shape中 m*n的值
print(t1)
print('t1_sum1',t1.sum())
t1[1, 2:] = np.nan # 将数组中第二行中的第2列到最后列变为nan
print('t1')
print(t1)
print('t1_sum2',t1.sum()) # nan与其他所有数值的运算结果都为nan
print("*"*50)
# 遍历每一列并计算每一列的nan数量
for i in range(t1.shape[1]):
temp_col = t1[:,i]
nan_num = np.count_nonzero(temp_col != temp_col) # 该列中nan的数量
# 若存在nan, 则求不含nan的均值, 并将nan赋值为均值
if nan_num != 0:
temp_not_nan_col = temp_col[temp_col == temp_col] # 获取该列中不是nan的部分
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean() # 将该列中nan的部分改为该列的均值
print(t1)
"""
t1
12
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
t1_sum1 66.0
t1
[[ 0. 1. 2. 3.]
[ 4. 5. nan nan]
[ 8. 9. 10. 11.]]
t1_sum2 nan
**************************************************
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
"""

浙公网安备 33010602011771号