目录
一、numpy概述
- Numerical Python,数值的Python,补充了Python语言所欠缺的数值计算能力。
- Numpy是其它数据分析及机器学习库的底层库。
- Numpy完全标准C语言实现,运行效率充分优化。
- Numpy开源免费。
官方文档: https://www.numpy.org
官方中文文档: https://www.numpy.org.cn/
1. numpy历史
- 1995年,Numeric,Python语言数值计算扩充。
- 2001年,Scipy->Numarray,多维数组运算。
- 2005年,Numeric+Numarray->Numpy。
- 2006年,Numpy脱离Scipy成为独立的项目。
2. numpy的核心:多维数组
- 代码简洁:减少Python代码中的循环。
- 底层实现:厚内核?+薄接口(Python),保证性能。
二、numpy基础
1. ndarray数组
用np.ndarray类的对象表示n维数组
import numpy as np
ary = np.array([1, 2, 3, 4, 5, 6])
print(type(ary))
1)内存中的ndarray对象
元数据(metadata)
存储对目标数组的描述信息,如:dim count、dimensions、dtype、data等。
实际数据
完整的数组数据
将实际数据与元数据分开存放,一方面提高了内存空间的使用效率,另一方面减少对实际数据的访问频率,提高性能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9MMpxi5n-1638019422028)(./img/ndarray_struct.png)]
2)ndarray数组对象的特点
- Numpy数组是同质数组,即所有元素的数据类型必须相同
- Numpy数组的下标从0开始,最后一个元素的下标为数组长度减1
3)ndarray数组对象的创建
np.array(任何可被解释为Numpy数组的逻辑结构)
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
print(a)
np.arange(起始值(0),终止值,步长(1))
import numpy as np
a = np.arange(0, 5, 1)
print(a)
b = np.arange(0, 10, 2)
print(b)
np.zeros(数组元素个数, dtype=‘类型’)
import numpy as np
a = np.zeros(10)
print(a)
np.ones(数组元素个数, dtype=‘类型’)
import numpy as np
a = np.ones(10)
print(a)
np.ones_like(类数组)
np.zeros_like(类数组)
import numpy as np
a = np.arange(10).reshape(2, 5)
print(a)
b = np.ones_like(a)
print(b)
c = np.zeros_like(a)
print(c)
4)ndarray对象属性的基本操作
**数组的维度:**np.ndarray.shape
import numpy as np
ary = np.array([1, 2, 3, 4, 5, 6])
print(type(ary), ary, ary.shape)
ary = np.array([
[1,2,3,4],
[5,6,7,8]
])
print(type(ary), ary, ary.shape)
**元素的类型:**np.ndarray.dtype
import numpy as np
ary = np.array([1, 2, 3, 4, 5, 6])
print(type(ary), ary, ary.dtype)
b = ary.astype(float)
print(type(b), b, b.dtype)
c = ary.astype(str)
print(type(c), c, c.dtype)
**数组元素的个数:**np.ndarray.size
import numpy as np
ary = np.array([
[1,2,3,4],
[5,6,7,8]
])
print(ary.shape, ary.size, len(ary))
5)ndarray对象的dtype属性的值
Numpy的内部基本数据类型
类型名 | 类型表示符 | 类型代码 |
---|
布尔型 | bool_ | ? | 有符号整数型 | int8(-128~127)/int16/int32/int64 | i1/i2/i4/i8 | 无符号整数型 | uint8(0~255)/uint16/uint32/uint64 | u1/u2/u4/u8 | 浮点型 | float16/float32/float64 | f2/f4/f8 | 复数型 | complex64/complex128 | C8/c16/c32 | 字节串型 | bytes_(兼容:Python字节) | S# | 字符串型 | str_(兼容:Python unicode)4字节 | ‘U#’ | 日期时间 | np.datetime64 | M8[Y] M8[M] M8[D] M8[h] M8[m] M8[s] | | | |
自定义复合类型
若希望ndarray中存储对象类型,numpy建议使用元组存储对象的属性字段值,然后把元组添加到ndarray中,ndarray提供了语法方便的处理这些数据。
import numpy as np
data=[
('zs', [90, 80, 85], 15),
('ls', [92, 81, 83], 16),
('ww', [95, 85, 95], 15)
]
第一种设置dtype的方式
a = np.array(data, dtype='U3, 3int32, int32')
print(a)
print(a[0]['f0'], ":", a[1]['f1'])
第二种设置dtype的方式
b = np.array(data, dtype=[
('name', 'str_', 2),
('scores', 'int32', 3),
('ages', 'int32', 1)
])
print(b[0]['name'], ":", b[0]['scores'])
第三种设置dtype的方式
c = np.array(data, dtype={
'names': ['name', 'scores', 'ages'],
'formats': ['U3', '3int32', 'int32']
})
print(c[0]['name'], ":", c[0]['scores'], ":", c.itemsize)
第四种设置dtype的方式
d = np.array(data, dtype={
'names': ('U3', 0),
'scores': ('3int32', 16),
'ages': ('int32', 28)
})
print(d[0]['names'], d[0]['scores'], d.itemsize)
Numpy的日期时间类型
类型名 | 类型表示符 | 类型代码 |
---|
日期时间 | np.datetime64 | M8[Y] M8[M] M8[D] M8[h] M8[m] M8[s] |
测试日期类型数组
f = np.array(['2011', '2012-01-01',
'2013-01-01 01:01:01','2011-02-01'])
f = f.astype('M8[D]')
f = f.astype('int32')
print(f[3]-f[0])
复数类型的矩阵
a = np.array([[1 + 1j, 2 + 4j, 3 + 7j],
[4 + 2j, 5 + 5j, 6 + 8j],
[7 + 3j, 8 + 6j, 9 + 9j]])
print(a.T)
for x in a.flat:
print(x.imag)
字节序前缀,用于多字节整数和字符串: </>/[=]分别表示小端/大端/硬件字节序。
类型字符码格式
<字节序前缀><维度><类型><字节数或字符数>
3i4 | 释义 |
---|
3i4 | 大端字节序,3个元素的一维数组,每个元素都是整型,每个整型元素占4个字节。 | <(2,3)u8 | 小端字节序,6个元素2行3列的二维数组,每个元素都是无符号整型,每个无符号整型元素占8个字节。 | U7 | 包含7个字符的Unicode字符串,每个字符占4个字节,采用默认字节序。 |
房价数据表示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zIauakIe-1638019422030)(./img/beijing_house_data.png)]
import numpy as np
data = [('宝星华庭一层带花园', '4室1厅', 298.79, 2598, 86951),
('绿地花园', '3室2厅', 154.62, 1000, 64675),
('沁园公寓', '3室2厅', 177.36, 1200, 67659)]
ary = np.array(data, dtype={
'names':['title', 'houseType',
'square', 'totalPrice', 'unitPrice'],
'formats':['20U', '10U', 'f8', 'f8', 'f8']
})
print(ary)
print(ary['totalPrice'])
day02
6) ndarray数组对象的维度操作
视图变维(数据共享): reshape() 与 ravel()
import numpy as np
a = np.arange(1, 9)
print(a)
b = a.reshape(2, 4)
print(b)
c = b.reshape(2, 2, 2)
print(c)
d = c.ravel()
print(d)
**复制变维(数据独立):**flatten()
e = c.flatten()
print(e)
a += 10
print(a, e, sep='\n')
直接变维:直接改变原数组对象的维度
a.shape = (2, 4)
print(a)
a.resize(2, 2, 2)
print(a)
7) 数组元素索引(下标)
数组对象[…, 页号, 行号, 列号]
下标从0开始,到数组len-1结束。
import numpy as np
a = np.array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
print(a, a.shape)
print(a[0])
print(a[0][0])
print(a[0][0][0])
print(a[0, 0, 0])
for i in range(a.shape[0]):
for j in range(a.shape[1]):
for k in range(a.shape[2]):
print(a[i, j, k])
8) ndarray数组切片操作
数组对象[起始位置:终止位置:步长, ...]
import numpy as np
a = np.arange(1, 10)
print(a)
print(a[:3])
print(a[3:6])
print(a[6:])
print(a[::-1])
print(a[:-4:-1])
print(a[-4:-7:-1])
print(a[-7::-1])
print(a[::])
print(a[:])
print(a[::3])
print(a[1::3])
print(a[2::3])
多维数组的切片操作
import numpy as np
a = np.arange(1, 28)
a.resize(3,3,3)
print(a)
print(a[1, :, :])
print(a[:, 1, :])
print(a[0, :, 1])
9) ndarray数组的运算
算术运算
+ - * / // % ** @ (矩阵乘法)
+= -= *= /= //= %= **=
示例:
import numpy as np
a = np.arange(1, 10).reshape(3, 3)
b = np.arange(9, 0, -1).reshape(3, 3)
print(a + b)
print(a - b)
print(a * b)
print(a ** b)
print(a @ b)
c = a * 2
print(c)
print(a ** 2)
数组乘法运算
数组有两种乘法运算: 数组乘积运算和矩阵点乘
数组乘积运算
C
=
A
×
B
C = A \times B
C=A×B
矩阵点乘运算
C
=
A
?
B
C = A \cdot B
C=A?B
数组乘积运算
Numpy 中用 * 运算符实现
要求数组的维度必须相等
矩阵点乘运算
矩阵点乘只有在第一个矩阵的列数(column)和第二个矩阵的行数(row)相同时才有意义
如: KaTeX parse error: Undefined control sequence: \ at position 26: …[\begin{array} \? ?a_{11}&a_{12}&a…
KaTeX parse error: Undefined control sequence: \ at position 26: …[\begin{array} \? ?b_{11}&b_{12} \…
KaTeX parse error: Undefined control sequence: \ at position 38: …[\begin{array} \? ?a_{11}b_{11}+a_…
示例:
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([[10, 20],
[30, 40],
[50, 60]])
c = a @ b
print(c)
示例:
比较运算
< <= > >= == !=
示例
import numpy as np
a = np.arange(1, 10).reshape(3, 3)
b = np.arange(9, 0, -1).reshape(3, 3)
print(a > b)
print(a > 3)
print(a == 5)
10) ndarray数组的掩码操作
布尔掩码
布尔掩码是用索引数组中对应位置的布尔值来挑选原数组中的元素,对应位置为True 的选取,为False 时则丢弃;返回选取元素的一维数组。
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
mask = [False, True, True, False, True, False, True, False, False]
print(a[mask])
索引掩码
索引掩码是用索引的长度生成一个新的数组,数组中的元素采用索引列表中的数字在原列表中取数据再放入索引中对应的位置。
import numpy as np
a = np.array(['Mi', 'Huawei', 'Apple', 'Oppo', 'Vivo'])
indices = [0, 3, 4, 1, 2]
print(a[indices])
11) 多维数组的组合与拆分
二维数组的操作
合并
import numpy as np
a = np.arange(1, 7).reshape(2, 3)
b = np.arange(7, 13).reshape(2, 3)
c = np.hstack((a, b))
print(c)
c = np.vstack((a, b))
print(c)
拆分
import numpy as np
c = np.array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
d, e = np.vsplit(c, 2)
print(d, e, sep='\n')
x, y, z = np.hsplit(c, 3)
print(x, y, z, sep='\n')
合并,拆分通用函数
np.concatenate((a, b), axis=0)
np.split(c, 2, axis=0)
axis 的取值
# 通过axis作为关键字参数指定组合的方向,取值如下:
# 二维数组:
# 0: 垂直方向(行)
# 1: 水平方向(列)
# 三维数组:
# 0: 深度方向(页)
# 1: 垂直方向(行)
# 2: 水平方向(列)
二维数组通用函数操作操作
import numpy as np
a = np.arange(1, 7).reshape(2, 3)
b = np.arange(7, 13).reshape(2, 3)
c = np.concatenate((a, b), axis=0)
print(c)
c = np.concatenate((a, b), axis=1)
print(c)
d = np.split(c, 2, axis=0)
print(d)
d = np.split(c, 2, axis=1)
print(d)
三维数组的操作
合并
import numpy as np
a = np.arange(1, 7).reshape(1, 2, 3)
b = np.arange(7, 13).reshape(1, 2, 3)
c = np.concatenate((a, b), axis=0)
print(c)
d = np.concatenate((a, b), axis=1)
print(d)
e = np.concatenate((a, b), axis=2)
print(e)
拆分
import numpy as np
c = np.array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
x, y = np.split(c, 2, axis=0)
print(x, y, sep='\n')
x, y = np.split(c, 2, axis=1)
print(x, y, sep='\n')
x, y, z = np.split(c, 3, axis=2)
print(x, y, z, sep='\n')
长度不等的数组组合:
numpy.pad(array,
pad_width=(前填充数, 后填充数),
mode='constant', constant_values=填充值)
示例
import numpy as np
a = np.array([1,2,3,4,5])
b = np.array([1,2,3,4])
b = np.pad(b, pad_width=(0, 1), mode='constant', constant_values=-1)
print(b)
c = np.vstack((a, b))
print(c)
简单的一维数组组合方案
a = np.arange(1,9)
b = np.arange(9,17)
c = np.row_stack((a, b))
print(c)
d = np.column_stack((a, b))
print(d)
Numpy 参考文档
https://numpy.org/doc/stable/reference/generated/numpy.split.html
https://numpy.org/doc/stable/reference/generated/numpy.concatenate.html
12)ndarray类的其他属性
import numpy as np
a = np.array([[1 + 1j, 2 + 4j, 3 + 7j],
[4 + 2j, 5 + 5j, 6 + 8j],
[7 + 3j, 8 + 6j, 9 + 9j]])
print(a.shape)
print(a.dtype)
print(a.ndim)
print(a.size)
print(a.itemsize)
print(a.nbytes)
print(a.real, a.imag, sep='\n')
print(a.T)
print([elem for elem in a.flat])
b = a.tolist()
print(b)
2. numpy文件操作
numpy加载文本文件
numpy提供了函数用于加载逻辑上可被解释为二维数组的文本文件,格式如下:
数据项1 <分隔符> 数据项2 <分隔符> ... <分隔符> 数据项n
例如:
AA,AA,AA,AA,AA
BB,BB,BB,BB,BB
...
或:
AA:AA:AA:AA:AA
BB:BB:BB:BB:BB
...
调用numpy.loadtxt()函数可以直接读取该文件并且获取ndarray数组对象:
加载文本文件
numpy提供了loadtxt()函数用于解析文本为ndarray
函数调用格式
numpy.loadtxt(
fname,
dtype=float,
delimiter=None,
converters=None
skiprows=0,
usecols=None,
unpack=False,
encoding=None,
...
)
loadtxt 参数详解
函数参数 | 参数解释 |
---|
fname | 文件路径 | dtype | 每列数据的数据类型。认为 float | delimiter | 分隔符(缺省值为空格) | converters | 转换器函数字典{1: func1, 2:func2} | skiprows | 过行数,默认0,不跳过 | usecols | 选择读取文件中的某些列。设置为相应列的索引列表。 | unpack | 是否按列拆包,是否单独拆分变量返回 | encoding | 编码。 |
例如:
import numpy as np
data = np.loadtxt("CustomerSurvival.csv",
skiprows=1,
delimiter=',')
print(data)
保存为文本文件
numpy提供了savetxt()函数用于将NDArray转为文本文件
函数调用格式
numpy.to_savetxtcsv(
fname=None,
X,
fmt='%.18e',
delimiter=' ',
newline='\n',
encoding=None
...
)
savetext()参数详解
方法参数 | 参数解释 |
---|
fname | 文件路径 | X | NDArray数组 | fmt | 浮点数的输出格式,默认’%.18e’ | delimiter | 分隔符,默认使用空格分隔(’ ') | newline | 换行符,默认:’\n’ | encoding | 编码(默认UTF-8)。 |
示例:
import numpy as np
data = np.arange(1, 10).reshape(3, 3)
print(data)
np.savetxt('temp.txt', data, '%d')
|