nan的注意点
- 两个nan不相等
# 输入
import numpy as np
np.nan == np.nan
# 输出
False
- nan具有传染性,nan和任何值计算都是nan
# 输入
t = np.arange(12).reshape(3, 4).astype('float')
t[1, 2] = np.nan
t
# 输出
array([[ 0., 1., 2., 3.],
[ 4., 5., nan, 7.],
[ 8., 9., 10., 11.]])
# 输入
# axis=0是在行上相加x11+x21+x31,最终的形状和行一样
t.sum(axis=0)
# 输出
array([12., 15., nan, 21.])
- 忽视nan的传染性的方法<后边补充numpy的聚合方法,聚合方法基本都有这样的nan安全版本>
# 输入
np.nansum(t, axis=0)
# 输出
array([12., 15., 12., 21.])
- 统计nan的个数
# 输入
t
# 输出
array([[ 0., nan, 2., 3.],
[ 4., nan, nan, 7.],
[ 8., 9., 10., 11.]])
# 输入
# 统计数组中非0数据的个数
np.count_nonzero(t)
# 输出
11
# 输入
# 统计nan的数量
np.count_nonzero(t!=t)
# 输出
3
- 替换nan时,一般使用均值、中位数或直接删除有缺失的行<后边补充使用均值处理numpy中的nan的例子>
聚合操作
numpy的聚合操作,可以直接作用在数组上,即既可以使用 np.方法名(data),也可以使用 data.方法名()。<两个不可以>
# 可以使用两种方式的聚合操作
np.sum(data):和 <data.sum()>
np.prod():积
np.mean():平均数
np.std():标准差
np.var():方差
np.min():最小值
np.max():最大值
np.argmin():最小值的索引
np.any():是否至少存在一个为真的元素
np.all():所有元素是否为真
# 只可以使用一种方法
np.median():中位数,没有data.median()
np.percentile():基于元素排序的统计值,没有data.percentile()
聚合操作中除了all方法和any方法,其他的都存在nan的安全方法,方法名前加nan即可。
用均值替换numpy中的nan值
# 输入
t
# 输出
array([[ 0., nan, 2., 3.],
[ 4., nan, nan, 7.],
[ 8., 9., 10., 11.]])
# 输入
# 用列均值填充数组的缺失值
def fill_ndarray(array):
# 计算列数
array_col_num = array.shape[1]
for i in range(array_col_num):
# 取出当前一列
array_col = array[:, i]
# 统计当前列nan的数量
nan_num = np.count_nonzero(array_col != array_col)
if nan_num != 0:
# 取出该列中非nan的值
array_not_nan = array_col[array_col == array_col]
# 计算非nan的均值
mean_not_nan = array_not_nan.mean()
# 将该列的nan值,替换为均值
array_col[np.isnan(array_col)] = mean_not_nan
return array_col_num
# 输入
fill_ndarray(t)
t
# 输出
array([[ 0., 9., 2., 3.],
[ 4., 9., 6., 7.],
[ 8., 9., 10., 11.]])
numpy中的条件表达式
np.where(条件, a, b):满足条件返回a,不满足返回b
# 输入
np.where(t>8, t, -1)
# 输出
array([[-1., 9., -1., -1.],
[-1., 9., -1., -1.],
[-1., 9., 10., 11.]])
和np.where()相似用法的_np.extract()_、np.clip():
np.extract(条件, 数组):数组中满足条件的选出来,不满足则丢弃
# 输入
np.extract(t>=8, t)
# 输出
array([ 9., 9., 8., 9., 10., 11.])
np.extract(数组, a, b):数组中比a小的全部赋值为a,比b大的全部赋值为b。
# 输入
t
# 输出
array([[ 0., 9., 2., 3.],
[ 4., 9., 6., 7.],
[ 8., 9., 10., 11.]])
# 输入
np.clip(t, 3, 10)
# 输出
array([[ 3., 9., 3., 3.],
[ 4., 9., 6., 7.],
[ 8., 9., 10., 10.]])
数组的拼接和分裂
- 数组的拼接
可以指定拼接轴的:np.concatenate([a1, a2], axis=0)
axis=0效果的拼接:np.vstack([a1, a2])
axis=1效果的拼接:np.hstack([a1, a2])
沿第三个轴进行拼接:np.dstack([a1, a2])
# 输入
a1 = np.random.randint(2, 20, (2, 2))
a1
# 输出
array([[ 5, 3],
[ 4, 11]])
# 输入
a2 = np.random.uniform(1, 10, (2, 2))
a2
# 输出
array([[2.2117397 , 5.8108252 ],
[3.17714435, 8.68351424]])
# 输入
a3 = np.concatenate([a1, a2], axis=1)
a3
# 输出
array([[ 5. , 3. , 2.2117397 , 5.8108252 ],
[ 4. , 11. , 3.17714435, 8.68351424]])
# 输入
a5 = np.hstack([a1, a2])
a5
# 输出
array([[ 5. , 3. , 2.2117397 , 5.8108252 ],
[ 4. , 11. , 3.17714435, 8.68351424]])
# 输入
a4 = np.concatenate([a1, a2], axis=0)
a4
# 输出
array([[ 5. , 3. ],
[ 4. , 11. ],
[ 2.2117397 , 5.8108252 ],
[ 3.17714435, 8.68351424]])
# 输入
a6 = np.vstack([a1, a2])
a6
# 输出
array([[ 5. , 3. ],
[ 4. , 11. ],
[ 2.2117397 , 5.8108252 ],
[ 3.17714435, 8.68351424]])
- 数组的分裂
np.split:默认沿着axis=0进行分裂,可以指定轴向。
np.hsplit :axis=1效果的分裂
np.vsplit :axis=0效果的分裂
# 输入
a = np.arange(24).reshape(4, 6)
a
# 输出
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
# 输入
a1, a2 = np.split(a, [2])
a1
# 输出
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
# 输入
a2
# 输出
array([[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
# 输入
a8, a9 = np.vsplit(a, [1])
a8
# 输出
array([[0, 1, 2, 3, 4, 5]])
# 输入
a9
# 输出
array([[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
# 输入
a3, a4, a5 = np.split(a, [2, 5], axis=1)
a3
# 输出
array([[ 0, 1],
[ 6, 7],
[12, 13],
[18, 19]])
# 输入
a4
# 输出
array([[ 2, 3, 4],
[ 8, 9, 10],
[14, 15, 16],
[20, 21, 22]])
# 输入
a5
# 输出
array([[ 5],
[11],
[17],
[23]])
# 输入
a6, a7 = np.hsplit(a, [2])
a6
# 输出
array([[ 0, 1],
[ 6, 7],
[12, 13],
[18, 19]])
# 输入
a7
# 输出
array([[ 2, 3, 4, 5],
[ 8, 9, 10, 11],
[14, 15, 16, 17],
[20, 21, 22, 23]])