大家好,又见面了,我是你们的朋友全栈君。
numpy
概述
▨ Numerical Python. 补充了python所欠缺的数值计算能力
▨ Numpy是其他数据分析及机器学习库的底层库
▨ Numpy完全标准C语言实现,运行效率充分优化
▨ Numpy开源免费
基本数据结构
类型名 | 类型表示符 |
---|---|
布尔类型 | bool_ |
有符号整型 | int8/16/32/64 |
无符号整型 | uint8/16/32/64 |
浮点型 | float16/32/64 |
复数型 | complex64/128 |
字符串型 | str_,每个字符32位Unicode |
可见是不允许存储特殊对象类型的, 因为 numpy 的目标主要是处理数字类型的
自定义复合类型
基础的数据类型无法满足需求, 我就是想传入复杂数据
方式一 – 直接设置
取元素只能通过索引 [n] 的形式去取
或者基于 默认别名 ‘fn’ 的形式 ( n 依旧是索引下标 )
import numpy as np data = [('zs', [90, 80, 70], 15), ('ls', [99, 89, 79], 16), ('ww', [91, 81, 71], 17)] # 2个Unicode字符,3个int32,1个int32组成的元组 ary = np.array(data, dtype='U2, 3int32, int32')
print(ary, ary.dtype) """ [('zs', [90, 80, 70], 15) ('ls', [99, 89, 79], 16) ('ww', [91, 81, 71], 17)] [('f0', '<U2'), ('f1', '<i4', (3,)), ('f2', '<i4')] """ print(ary[1][2], ary[1]['f2']) # 16 16
方式二 – 带别名设置
可以通过别名进行获取
import numpy as np data = [('zs', [90, 80, 70], 15), ('ls', [99, 89, 79], 16), ('ww', [91, 81, 71], 17)] # 第二种设置dtype的方式 为每个字段起别名 ary = np.array(data, dtype=[('name', 'str_', 2), # 别名, 类型, 元素个数 ('scores', 'int32', 3), ('age', 'int32', 1)])
print(ary[2]['age']) # 17
方式三 – 字典形式设置
键值对形式相同位置简历映射,
name 键统一设置 别名
formats 键统一设置 类型和数量
是结合了一二两种方式的结果
import numpy as np data = [('zs', [90, 80, 70], 15), ('ls', [99, 89, 79], 16), ('ww', [91, 81, 71], 17)] # 第三种设置dtype的方式 ary = np.array(data, dtype={ 'names': ['name', 'scores', 'age'], 'formats': ['U2', '3int32', 'int32']})
print(ary[2]['scores']) # [91 81 71]
方式四 – 字节方式设置
依旧是字典格式
使用别名作为 键
值 为 元组形式
( ‘数量类型’, 定位字节起点 )
可以手动指定每个字段的存储偏移量
举栗子
(‘U3’,0) Unicode 字符是32 位, 占4字节, 三个占位 12字节, 在 12 字节处结束
(‘3int32’, 16) 定位在 16 字节处 , 即距离上面的又空了 4 字节, 然后 又是占位 12字节 , 在 28 字节处结束
(‘int32’, 28) 定位在 28 字节处, 占位 12 字节, 在 40 字节处结束
import numpy as np data = [('zs', [90, 80, 70], 15), ('ls', [99, 89, 79], 16), ('ww', [91, 81, 71], 17)] # 第四种设置dtype的方式 手动指定每个字段的存储偏移字节数 # name从0字节开始输出,输出3个Unicode # scores从16字节开始输出,输出3个int32 ary = np.array(data, dtype={ 'name': ('U3', 0), 'scores': ('3int32', 16), 'age': ('int32', 28)})
print(ary[0]['name']) # zs
存储日期类型数据
只能识别 YYYY-MM-DD HH:MM:SS 的格式 , – 换成 / 就不行
可以进行一定程度的运算
# ndarray数组中存储日期类型数据 dates = np.array(['2011', '2012-01-01', '2013-01-01 11:11:11', '2011-02-01']) print(dates, dates.dtype) # ['2011' '2012-01-01' '2013-01-01 11:11:11' '2011-02-01'] <U19 dates = dates.astype('M8[D]') # datetime64 精确到 Day print(dates, dates.dtype) # ['2011-01-01' '2012-01-01' '2013-01-01' '2011-02-01'] datetime64[D] print(dates[-1] - dates[0]) # 31 days dates = dates.astype('int32') print(dates, dates.dtype) # [14975 15340 15706 15006] int32
类型字符码 – 数据类型的简写
类型 | 字符码 |
---|---|
bool_ | ? |
int8/16/32/64 | i1/2/4/8 |
uint8/16/32/64 | u1/2/4/8 |
float16/32/64 | f2/4/8 |
complex64/128 | c8/16 |
str_ | U |
datetime64 | M8[Y/M/D/h/m/s] |
数组 – nadarray 对象
概念
类似于列表, 可以多维嵌套, 但是要求必须内部存储相同类型的数据
即同质数组, 相同的数据类型的空间占用相同, 且查询方便
空间结构
ary = np.array([1, 2, 3, 4, 5]) """ _______________________________________ a -----> | nadarray 对象 | | | | 元数据 | |_______ | |_dim___| | |_dtype_| _____________________ | |_data__| ---> |_1_|_2_|_3_|_4_|_5_| | |_shape_| ---> (5,) | |_______|______________________________| """
元数据 (metadata)
存储对数组的描述信息, 如 : dim count, dtype, dara, shape 等
实际数据
完整的数组数据, 将实际数据与元数据分开存放
一方面提高了内存空间的使用效率
另一方面减少对实际数据的访问频率,提高性能。
创建语法
np.array([[], [], []]) # 直接创建 np.arange(0, 10, 1) # 序列创建 np.zeros(10) # 全 0 创建 np.ones(10) # 全 1 创建 np.zeros_like(ary) # 仿结构创建 全 0 数组 np.ones_like(ary) # 仿结构创建 全 1 数组
示例
import numpy as np a = np.array([1, 2, 3, 4, 5, 6]) print(a) # [1 2 3 4 5 6] b = np.arange(7, 13, 1) print(b) # [ 7 8 9 10 11 12] c = np.zeros(6) print(c) # [ 0. 0. 0. 0. 0. 0.] d = np.ones(6) print(d) # [ 1. 1. 1. 1. 1. 1.] print(d / 2) # [ 0.5 0.5 0.5 0.5 0.5 0.5] e = np.array([[1, 2, 3], [4, 5, 6]]) print(np.ones_like(e)) """ [[1 1 1] [1 1 1]] """
nadarray 对象属性 – 基本操作
数组维度
ary.shape 数组维度
可以直接进行更改数组结构
但是更改需要合理, 比如 6 元素 更改为 3*3 需要9元素则无法满足从而报错
ary = np.array([1, 2, 3, 4, 5, 6]) print(ary, ary.shape) # [1 2 3 4 5 6] (6,)
ary.shape = (2, 3) print(ary, ary.shape) """ [[1 2 3] [4 5 6]] (2, 3) """ print(ary[1][1]) # 5
元素类型
ary.dtype 数组元素类型
ary.astype 修改元素类型
数据类型直接更改是不可取的, 需要使用 astype 方法进行更改
利用重新开辟新的空间来赋值存储
即此方法不会改变原值, 需要用返回值进行复制
# 数组元素类型 ary = np.array([1, 2, 3, 4, 5, 6]) print(ary, ary.dtype) # [1 2 3 4 5 6] int32
# ary.dtype = np.int64 # print(ary, ary.dtype)
# 更改数据类型 b = ary.astype('float32') print(ary, ary.dtype) # [1 2 3 4 5 6] int32 print(b, b.dtype) # [ 8.58993459e+09 1.71798692e+10 2.57698038e+10] float32
数组元素个数
ary.size 返回数组元素个数
len(ary) 返回数组元素个数
ary = np.array([1, 2, 3, 4, 5, 6]) print(ary.size) # 6 print(len(ary)) # 6
数组元素索引
下标
# 数组元素的索引 ary = np.arange(1, 9) ary.shape = (2, 2, 2) print(ary, ary.shape) """ [[[1 2] [3 4]] [[5 6] [7 8]]] (2, 2, 2) """ print(ary[0]) # 0页数据 """ [[1 2] [3 4]] """ print(ary[0][0]) # 0页0行数据 """ [1 2] """ print(ary[0][0][0]) # 0页0行0列数据 """ 1 """ print(ary[0, 0, 0]) # 0页0行0列数据 """ 1 """ # 使用for循环,把ary数组中的元素都遍历出来。 for i in range(ary.shape[0]): for j in range(ary.shape[1]): for k in range(ary.shape[2]): print(ary[i, j, k], end=' ') # 1 2 3 4 5 6 7 8
ndarray对象 – 维度操作详解
视图变维
reshape() – 改变维度
在原数据上建立的 映射, 即源数据的刚刚会影响其他视图的展示
import numpy as np a = np.arange(1, 7) # print(a, a.shape) # [1 2 3 4 5 6] (6,) # 测试视图变维 reshape() ravel() b = a.reshape(2, 3) print(b, b.shape) """ [[1 2 3] [4 5 6]] (2, 3) """ a[0] = 999 print(b, b.shape) """ [[999 2 3] [ 4 5 6]] (2, 3) """
ravel() – 扁平化处理
将高维度变为一维
print(b, b.shape) """ [[999 2 3] [ 4 5 6]] (2, 3) """ c = b.ravel() print(c, c.shape) # [999 2 3 4 5 6] (6,)
总结
视图变维是基于源文件的, 因此不会开辟新的内存空间
ravel 的平铺可以简单的展开数组进行一维输出
复制变维
flatten() – 扁平化处理
使用方法和结果同 ravel
但是是重新开辟空间处理, 源数据与新数据是空间隔离互不干涉的
import numpy as np # 复制变维 flatten() copy() a = np.array([[1, 2, 3], [4, 5, 6]]) b = a.flatten() # 扁平化 print(b, b.shape) # [1 2 3 4 5 6] (6,) a[0] = 1 print(a, a.shape) """ [[1 1 1] [4 5 6]] (2, 3) """ print(b, b.shape) # [1 2 3 4 5 6] (6,)
就地变维
shape()
resize()
直接基于源数据的更改
import numpy as np # 就地变维 a = np.arange(1, 7) a.resize(3, 2)
print(a, a.shape) """ [[1 2] [3 4] [5 6]] (3, 2) """
ndarray对象 – 索引操作
ndarray数组 – 切片
[::] / [:] 全部
[m:n] m到n 左包右不包 , 为负数表示倒数 m / n 位
[::n] 步长
[::-1] 倒序
切片是会生成新的对象, 因此 直接使用 [::] 来代替复制是可以的
""" demo05_shape.py """ import numpy as np a = np.arange(1, 10) print(a) # [1 2 3 4 5 6 7 8 9] print(a[:3]) # [1 2 3] print(a[3:6]) # [4 5 6] print(a[6:]) # [7 8 9]
print(a[::-1]) # [9 8 7 6 5 4 3 2 1] print(a[:-4:-1]) # [9 8 7] print(a[::]) # [1 2 3 4 5 6 7 8 9]
print(a[::3]) # [3 6 9] print(a[1::3]) # [3 6 9] print(a[2::3]) # [3 6 9]
高维切片
[ 行的切片 , 列的切片 ]
# 高维数组切片 a = a.reshape(3, 3) print(a, a.shape) """ [[1 2 3] [4 5 6] [7 8 9]] (3, 3) """ print(a[:2, :2]) """ [[1 2] [4 5]] """ print(a[:2, 0]) """ [1 4] """
ndarray数组 – 掩码操作
非常方便两个数组的重叠映射, 将 True 的元素输出
import numpy as np a = np.arange(1, 8) mask = a > 5 print(a) # [1 2 3 4 5 6 7] print(mask) # [False False False False False True True] print(a[mask]) # [6 7]
此方法可以进行相当多的炫酷操作, 如下
import numpy as np # 输出100以内3与7的公倍数。 a = np.arange(1, 100) mask = (a % 3 == 0) & (a % 7 == 0) print(a[mask]) # [21 42 63 84]
# 利用掩码运算对数组进行排序 p = np.array(['Mi', 'Apple', 'Huawei', 'Oppo']) r = [1, 3, 2, 0] print(p[r]) # ['Apple' 'Oppo' 'Huawei' 'Mi']
多维数组 – 组合与拆分
垂直方向操作
vstack – 合并
vsplit – 拆分
垂直方向合并及列合并, 增加列
拆分需要合理, 不合理的炒粉会报错 ( 5个拆成 4 个之类的 )
# 垂直方向合并 c = np.vstack((a, b))
# 把c拆成2份, a与b a, b = np.vsplit(c, 2)
import numpy a = numpy.array([1, 2, 3]) b = numpy.array([4, 5, 6]) c = numpy.vstack((a, b)) # print(c) """ [[1 2 3] [4 5 6]] """ a, b = numpy.vsplit(c, 2) print(a) # [[1 2 3]] print(b) # [[4 5 6]]
水平方向操作
hstack – 合并
hsplit – 拆分
水平方向合并及行合并, 增加行长度
拆分需要合理, 不合理的炒粉会报错 ( 5个拆成 4 个之类的 )
# 水平方向合并 c = np.hstack((a, b)) # 把c拆成2份, a与b a, b = np.hsplit(c, 2)
import numpy a = numpy.array([1, 2, 3]) b = numpy.array([4, 5, 6]) c = numpy.hstack((a, b)) print(c) # [1 2 3 4 5 6] a, b = numpy.hsplit(c, 2) print(a) # [1 2 3] print(b) # [4 5 6]
深度方向操作
dstack – 合并
dsplit – 拆分
深度方向合并即维度合并, 增加维度
拆分需要合理, 不合理的炒粉会报错 ( 比如拆 3 份 )
# 深度方向合并 c = np.dstack((a, b)) # 把c拆成2份, a与b a, b = np.dsplit(c, 2)
import numpy a = numpy.array([1, 2, 3]) b = numpy.array([4, 5, 6]) c = numpy.dstack((a, b)) print(c) """ [[[1 4] [2 5] [3 6]]] """ a, b = numpy.dsplit(c, 2) print(a) """ [[[1] [2] [3]]] """ print(b) """ [[[4] [5] [6]]] """
import numpy a = numpy.array([[1, 2, 3], [4, 5, 6]]) b = numpy.array([[7, 8, 9], [10, 11, 12]]) c = numpy.dstack((a, b)) # print(c) """ [[[ 1 7] [ 2 8] [ 3 9]] [[ 4 10] [ 5 11] [ 6 12]]] """ a, b = numpy.dsplit(c, 2) # print(a) """ [[[1] [2] [3]] [[4] [5] [6]]] """ # print(b) """ [[[ 7] [ 8] [ 9]] [[10] [11] [12]]] """
多维数组 – 组合与拆分相关函数
concatenate( ) – 组合
split () – 拆分
# 把a与b按照axis的轴向进行组合
# axis 数组组合的轴向 # 0:垂直 1:水平 2:深度 # 注意:若axis=2,则要求a与b都是3维数组
c = np.concatenate((a, b), axis=0)
# 把c按照axis的轴向拆成2部分 a, b = np.split(c, 2, axis=0)
简单的一维数组的组合方案
row_stack – 行合并
column_stack – 列合并
# 把两个一维数组摞在一起成两行 c = np.row_stack((a, b)) # 把两个一维数组并在一起成两列 c = np.column_stack((a, b))
import numpy a = numpy.array([1, 2, 3, 4, 5, 6]) b = numpy.array([7, 8, 9, 10, 11, 12]) c = numpy.row_stack((a, b)) print(c) """ [[ 1 2 3 4 5 6] [ 7 8 9 10 11 12]] """ d = numpy.column_stack((a, b)) print(d) """ [[ 1 7] [ 2 8] [ 3 9] [ 4 10] [ 5 11] [ 6 12]] """
ndarray数组 – 其他属性
▨ shape, dtype, size ….
▨ ndim 维数 n维数组的那个n
▨ itemsize 每个元素的字节数
▨ nbytes 数组占用内存的总字节数
▨ real 复数数组的数据的实部
▨ imag 复数数组的数据的虚部
▨ T 返回数组的转置视图
▨ flat 返回数组的扁平迭代器
""" demo09_attr.py 其他属性 """ import numpy as np data = np.array([[1 + 1j, 2 + 4j, 3 + 7j], [4 + 2j, 5 + 5j, 6 + 8j], [7 + 3j, 8 + 6j, 9 + 9j]]) print(data.ndim) # 2 print(data.dtype, data.itemsize) # complex128 16 print(data.nbytes) # 144 print(data.real) """ [[ 1. 2. 3.] [ 4. 5. 6.] [ 7. 8. 9.]] """
print(data.imag) """ [[ 1. 4. 7.] [ 2. 5. 8.] [ 3. 6. 9.]] """ print(data.T) """ [[ 1.+1.j 4.+2.j 7.+3.j] [ 2.+4.j 5.+5.j 8.+6.j] [ 3.+7.j 6.+8.j 9.+9.j]] """ print([x for x in data.flat]) # [(1+1j), (2+4j), (3+7j), (4+2j), (5+5j), (6+8j), (7+3j), (8+6j), (9+9j)]
转载于:https://www.cnblogs.com/shijieli/p/10846772.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/106825.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...