前言:之前一直使用numpy,但总是一点一点搜索,需要什么搜索什么,积累多了,也就有点新的感悟。所以想把这些知识系统地整理出来,方便未来的自己查阅,也分享给朋友们。另外,numpy的速度跟python的for循环的速度比较就是降维打击,学好numpy进行数据处理真的非常非常非常有必要,有什么整理不当错误的地方欢迎大家批评指正,一起学习,共同进步。注:示例用到的文件“apple.csv”下载链接在文末
第一类:从已有的数组创建数组(重点)
np.asarray
,将python列表或者元组、或者numpy数组转变成numpy数组
numpy创建数组的方式个人觉得可以分别两类,应对不同的场景需求。第一种也是最常用的一种就是使用python的列表或者元组进行创建
,这是我们将python的列表变成numpy数组运算的关键。
import numpy as np
lista = [1, 2, 3, 4]
array_1 = np.asarray(lista)
生成的array_1
就是numpy的数组,后续numpy的操作都可以运用在这个对象里面
np.array,这个函数跟np.asarray这个函数基本没有差别,可以换着使用
import numpy as np
lista = [1, 2, 3, 4]
array_1 = np.array(lista)
第二类:通过numpy的内置函数创建特定数组
numpy.empty
,numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组,数组元素的值是随机值
import numpy as np
x = np.empty([5,2], dtype = int)
print (x)
结果为,元素都是随机值,没有规律
[[ 45146880 0]
[201863463028 502511173743]
[481036337268 498216206453]
[433791696928 489626271858]
[489626271855 399431958528]]
numpy.zeros
,创建指定大小、且数组元素都为0的数组
import numpy as np
x = np.zeros((5, 3),dtype=int)
print(x)
结果为,元素都为0
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
numpy.ones
,创建指定大小、且数组元素都为1的数组
import numpy as np
x = np.ones((5, 3),dtype=int)
print(x)
结果为,元素都为1
[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]]
numpy.arange
,创建一个在数据范围内的序列一维数组,可以指定起点、终点、步长、和数据类型
import numpy as np
x = np.arange(start=1, stop=5, step=1, dtype=int)
print(x)
结果为,整数序列的一维数组
[0 1 2 3 4]
numpy.linspace
,创建一个等差数列一维数组
import numpy as np
x = np.linspace(start=1, stop=10, num=10, endpoint=True, dtype=int) # 从1到10生成步长为1的10个数字,endpoint=True表示包含终点
print(x)
结果为,一个步长为1的等差数列
[ 1 2 3 4 5 6 7 8 9 10]
numpy.logspace
,创建一个等比数列一维数组
import numpy as np
x = np.logspace(start=0, stop=9, num=10, endpoint=True, base=2, dtype=int) # 表示从2的0次方一直到2的9次方生成10个元素
print(x)
结果为,一个步长为2的等比数列
[ 1 2 4 8 16 32 64 128 256 512]
有些时候,我们需要用到判断数据的某些属性,这些属性有助于我们理解和使用numpy数组。下面进行演示。
# 创建一个等比数组
import numpy as np
x = np.logspace(start=0, stop=9, num=10, endpoint=True, base=2, dtype=int)
# 将数组的形状变成二维
y = np.reshape(x,(2, 5))
属性 | 说明 | 运行 | 结果 |
---|---|---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 | y.ndim | 2 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 | y.shape | (2, 5) |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 | y.size | 10 |
ndarray.dtype | ndarray 对象的元素类型 | y.dtype | dtype(‘int64’) |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 | y.itemsize | 8 |
ndarray.flags | ndarray 对象的内存信息 | y.flags | |
ndarray.real | ndarray元素的实部 | y.real | array([[ 1, 2, 4, 8, 16], [ 32, 64, 128, 256, 512]]) |
ndarray.imag | ndarray 元素的虚部 | y.imag | array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
如果我们想逐个获取numpy数组中的元素,我们需要通过数组的下标进行选取,虽然一般来说我们不会这么做。创建一个y数组
# 创建一个等比数组
import numpy as np
x = np.logspace(start=0, stop=9, num=10, endpoint=True, base=2, dtype=int)
# 将数组的形状变成二维
y = np.reshape(x,(2, 5))
# y的值是
array([[ 1, 2, 4, 8, 16],
[ 32, 64, 128, 256, 512]])
获取数组元素的格式如下:数组名[一维下标,二维下标,三维下标,...]
,如果数组是二维数组,那么格式简化为:数组名[行下标,列下标]
,注意,下标都是从0开始的。例如
y[0,1] # 结果为2
y[0,2] # 结果为4
如果我们想一次性连续获取numpy多个数组元素,我们可以用到切片操作。创建一个y数组
# 创建一个等比数组
import numpy as np
x = np.logspace(start=0, stop=9, num=10, endpoint=True, base=2, dtype=int)
# 将数组的形状变成二维
y = np.reshape(x,(2, 5))
# y的值是
array([[ 1, 2, 4, 8, 16],
[ 32, 64, 128, 256, 512]])
切片操作的格式如下:数组名[一维起始下标:一维终点下标:一维步长,二维起始下标:二维终点下标:二维步长,三维起始下标:三维终点下标:三维步长,...]
,其中默认的步长都为1,可以忽略不指定;第二,切片不包含“终点下标”。
例如,不指定步长
y[0:2,2:5] # 结果为,选取第0和第1行,选取第2、3、4列
array([[ 4, 8, 16],
[128, 256, 512]])
例如,指定步长
y[0:2,2:5:2] # 结果为,选取第0和第1行,选取第2、4列(因为步长为2)
array([[ 4, 16],
[128, 512]])
第三个注意点
,可以忽略“起始下标”和“终点下标”,变成数组名[::一维步长,::二维步长,::三维步长,…],表示全选该维度的数组元素,例如
例如,不指定步长
y[0:2,:] # 结果为,选取第0和第1行,全选第二维度的所有元素
array([[ 1, 2, 4, 8, 16],
[ 32, 64, 128, 256, 512]])
例如,指定步长
y[0:2,::2] # 结果为,选取第0和第1行,以步长为2全选第二维度的所有元素
array([[ 1, 4, 16],
[ 32, 128, 512]])
第四个注意点
,可以用省略号...
来全选多个维度的元素。例如假设有个数组的形状是y.shape = (64, 128, 128, 3),它表示64张尺寸大小都为128像素的彩色图片,如果你想得到前面的30张图片,后面的30张图片不要的话,你可以表示为y[0:31,…]。当然你也可以有另外一种写法就是忽略“起始下标”和“终点下标”:y[0:31,:,:,:],可以明显感受到,省略号会更加地整洁方便。
假设现在我们有两三个数组都是需要进行同一个操作,当然你可以用个for循环让每个数组都运算一遍,但是会很慢。如果你将这几个数组组合成一个数组然后进行运算,速度会很快。在实际很多业务上面,往往也不允许我们将数组分开计算,必须组合成一个进行计算。
先来创建两个数组便于后续作为例子
import numpy as np
a = np.arange(36).reshape(3, 3, 4)
b = a / 10
a数组的形状为
a.shape = (3, 3, 4)
b数组的形状为
b.shape = (3, 3, 4)
np.concatenate,指定维度将多个数组进行组合
y = np.concatenate([a, b], axis=0) # 在第0维度进行组合
print(y.shape)
结果为(6, 3, 4)
y = np.concatenate([a, b], axis=1) # 在第1维度进行组合
print(y.shape)
结果为(3, 6, 4)
y = np.concatenate([a, b], axis=2) # 在第2维度进行组合
print(y.shape)
结果为(3, 3, 8)
其它组合函数包括:np.hstack
水平组合、np.vstack
垂直组合、np.dstack
深度组合、np.column_stack
列组合、np.row_stack
行组合。这些函数都可以用np.concatenate
来代替实现,所以我不想跟你们做过多的解释,记住一句话,数组的组合学会np.concatnate
就够用了。如果你们实在想了解,评论区告诉我,然后我再来补充。
跟数组的切片相似的操作还有数组的分割,有时候我们需要对数组拆分之后逐一进行处理就需要用到数组的分割。
先来创建两个数组便于后续作为例子
import numpy as np
a = np.arange(36).reshape(3, 3, 4)
b = a / 10
a数组的形状为
a.shape = (3, 3, 4)
b数组的形状为
b.shape = (3, 3, 4)
np.split,指定维度将多个数组进行分割
y = np.split(a, 3,axis=0) # 在第0维度将数组a平均分为三个数组
print(y[0].shape) # 结果为(1,3,4)
print(y[1].shape) # 结果为(1,3,4)
print(y[2].shape) # 结果为(1,3,4)
y = np.split(a, 3,axis=1) # 在第1维度将数组a平均分为三个数组
print(y[0].shape) # 结果为(3,1,4)
print(y[1].shape) # 结果为(3,1,4)
print(y[2].shape) # 结果为(3,1,4)
y = np.split(a, 4,axis=2) # 在第1维度将数组a平均分为四个数组
print(y[0].shape) # 结果为(3,3,1)
print(y[1].shape) # 结果为(3,3,1)
print(y[2].shape) # 结果为(3,3,1)
print(y[3].shape) # 结果为(3,3,1)
其它分割函数包括:np.hsplit
水平分割、np.vsplit
垂直分割、np.dsplit
深度分割。这些函数都可以用np.split
来代替实现,所以我不想跟你们做过多的解释,记住一句话,数组的组合学会np.split
就够用了。如果你们实在想了解,评论区告诉我,然后我再来补充。np.split函数还可以指定位置进行分割,但是用处不多,这就有兴趣的同学可以自行了解
import numpy as np
x = np.array([0,1,2,3,4,5,6,7,8])
print (np.split(x,3))
print (np.split(x,[3,5,6,9])) # 指定下标位置进行分割
print(np.split(x,[3,5,6,8])) # 指定下标位置进行分割
输出:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
[array([0, 1, 2]), array([3, 4]), array([5]), array([6, 7, 8]), array([], dtype=int32)]
[array([0, 1, 2]), array([3, 4]), array([5]), array([6, 7]), array([8])]
如果你想形状为(12,2)的数组修改成形状(4, 6)的数组,或者是(24,)的数组,那么我们该用那个函数呢。
array.reshape
,将数组array的形状进行修改,这个函数是重点,基本可以满足自己所有的要求了
import numpy as np
a = np.arange(36)
print(a.shape) # 输出(36,)
b = a.reshape((3, 3, 4))
print(b.shape) # 输出(3, 3,4)
array.flatten
,将数组array的形状进行展平
import numpy as np
a = np.arange(36).reshape((3, 3, 4))
print(a.shape) # 输出(3, 3,4)
b = a.flatten()
print(b.shape) # 输出(36,)
数组转换成列表
import numpy as np
a = np.arange(36).reshape((3, 3, 4))
b = a.tolist()
print(type(a)) # 输出为
print(type(b)) # 输出为
array.astype,转换数据的数据类型
将整型int64数组变成浮点型float64数组
import numpy as np
a = np.arange(36).reshape((3, 3, 4))
b = a.astype(np.float64)
print(a.dtype) # 输出为int64
print(b.dtype) # 输出为float64
将整型int64数组变成整型int32数组
import numpy as np
a = np.arange(36).reshape((3, 3, 4))
b = a.astype(np.int32)
print(a.dtype) # 输出为int64
print(b.dtype) # 输出为int32
其它数据类型都可以相互转换,但是如果浮点型转成整型小数点后的数据会缺失,这点要注意。下面是numpy数据类型的总结。
注意,使用的时候在’名称‘对前面加上’np‘才可以。
应该是np.int32
而不是int32
名称 | 描述 |
---|---|
bool_ | 布尔型数据类型(True 或者 False) |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) |
int8 | 字节(-128 to 127) |
int16 | 整数(-32768 to 32767) |
int32 | 整数(-2147483648 to 2147483647) |
int64 | 整数(-9223372036854775808 to 9223372036854775807) |
uint8 | 无符号整数(0 to 255) |
uint16 | 无符号整数(0 to 65535) |
uint32 | 无符号整数(0 to 4294967295) |
uint64 | 无符号整数(0 to 18446744073709551615) |
float_ | float64 类型的简写 |
float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 |
complex64 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
np.eye
、np.savetxt
将numpy数组的数据保存到txt文件中,用到的函数np.eye
、np.savetxt
import numpy as np
i2 = np.eye(2) # 创建一个(2,2)的单位矩阵
np.savetxt('eye.txt', i2) # 将数组存储到文件eye.txt中
np.loadtxt
、np.average
、np.mean
读取csv文件,并计算数组的加权平均值和算术平均值,用到的函数np.loadtxt
、np.average
、np.mean
import numpy as np
c,v = np.loadtxt('apple.csv', # 文件名
delimiter=',', # 设置英文逗号为分隔符
usecols=(4,5), # 只获取第4字段、第5字段的数据
unpack=True,# 拆分储存不同列的数据
skiprows=1 # 表示csv文件的第一行是列名
)
vwap = np.average(c, weights=v) # 以数组v为权重,计算数组c的加权平均值
mean = np.mean(c) # 计算数组c的算术平均值
np.max
、np.min
、np.ptp
计算数组的最大值和最小值,并求最大值和最小值的差值,用到的函数np.max
、np.min
、np.ptp
import numpy as np
c,v = np.loadtxt('apple.csv', # 文件名
delimiter=',', # 设置英文逗号为分隔符
usecols=(4,5), # 只获取第4字段、第5字段的数据
unpack=True,# 拆分储存不同列的数据
skiprows=1 # 表示csv文件的第一行是列名
)
maxc = np.max(c) # 最大值702.1
minc = np.min(c) # 最小值90.28
ptpc = np.ptp(c) # 范围611.82
np.median
、np.var
、np.msort
、np.std
简单统计分析,给数据排序、计算数组的中位数、方差,标准差,用到的函数np.median
、np.var
、np.msort
、np.std
import numpy as np
c,v = np.loadtxt('apple.csv', # 文件名
delimiter=',', # 设置英文逗号为分隔符
usecols=(4,5), # 只获取第4字段、第5字段的数据
unpack=True,# 拆分储存不同列的数据
skiprows=1 # 表示csv文件的第一行是列名
)
medianc = np.median(c) # 使用np直接计算中位数
varc = np.var(c) # 使用np直接计算方差
# 也可以根据中位数和方差的定义来进行计算
sorted_c = np.msort(c) # 给数组c进行从小到大的排序
np.diff
、np.std
、np.log
计算数组相邻两个元素的差值,计算收益率和对数收益率,用到的函数np.diff
、np.std
、np.log
import numpy as np
c,v = np.loadtxt('apple.csv', # 文件名
delimiter=',', # 设置英文逗号为分隔符
usecols=(4,5), # 只获取第4字段、第5字段的数据
unpack=True,# 拆分储存不同列的数据
skiprows=1 # 表示csv文件的第一行是列名
)
ret = np.diff(c) / c[:-1] # 计算收益率
std_c = np.std(ret) # 计算收益率的标准差,标准差越小,说明收益率越稳定
ret2 = np.diff(np.log(c)) # 计算对数收益率,将受益取对数,然后再进行计算
np.where
、np.take
根据指定的条件返回所有满足条件的数组元素的索引值;按照索引值从数组中取出相应的元素。用到的函数np.where
、np.take
import numpy as np
c,v = np.loadtxt('apple.csv', # 文件名
delimiter=',', # 设置英文逗号为分隔符
usecols=(4,5), # 只获取第4字段、第5字段的数据
unpack=True,# 拆分储存不同列的数据
skiprows=1 # 表示csv文件的第一行是列名
)
indices = np.where(c > 300) # 找出数组元素大于300元素的下标
prices = np.take(c, indices) # # 找出指定索引的数组元素
np.maxmum
、np.minimum
求多个数组中,每个元素的对应最大值、最小值,用到的函数np.maxmum
、np.minimum
import numpy as np
t1,t2,t3 = np.loadtxt('apple.csv', # 文件名
delimiter=',', # 设置英文逗号为分隔符
usecols=(2,3,4), # 只获取第2字段、第3字段、第4字段的数据
unpack=True,# 拆分储存不同列的数据
skiprows=1 # 表示csv文件的第一行是列名
)
max_t = np.maximum(t1,t2,t3) # 取三个数组中对应元素的最大值
min_t = np.minimum(t1,t2,t3) # 取三个数组中对应元素的最小值
结语:示例用到的文件"apple.csv"请自行下载:https://www.kaggle.com/fayomi/apple-stock-prices-from-20102017
`、`np.minimum`
```python
import numpy as np
t1,t2,t3 = np.loadtxt('apple.csv', # 文件名
delimiter=',', # 设置英文逗号为分隔符
usecols=(2,3,4), # 只获取第2字段、第3字段、第4字段的数据
unpack=True,# 拆分储存不同列的数据
skiprows=1 # 表示csv文件的第一行是列名
)
max_t = np.maximum(t1,t2,t3) # 取三个数组中对应元素的最大值
min_t = np.minimum(t1,t2,t3) # 取三个数组中对应元素的最小值
结语:示例用到的文件"apple.csv"请自行下载:https://www.kaggle.com/fayomi/apple-stock-prices-from-20102017