前言:之前一直使用numpy,但总是一点一点搜索,需要什么搜索什么,积累多了,也就有点新的感悟。所以想把这些知识系统地整理出来,方便未来的自己查阅,也分享给朋友们。另外,numpy的速度跟python的for循环的速度比较就是降维打击,学好numpy进行数据处理真的非常非常非常有必要,有什么整理不当错误的地方欢迎大家批评指正,一起学习,共同进步。注:示例用到的文件“apple.csv”下载链接在文末
numpy基础
numpy创建数组的两类方法
-
第一类:从已有的数组创建数组(重点)
-
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数组有哪些常用的属性
有些时候,我们需要用到判断数据的某些属性,这些属性有助于我们理解和使用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数组元素
如果我们想逐个获取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数组元素–切片操作
如果我们想一次性连续获取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,:,:,:],可以明显感受到,省略号会更加地整洁方便。
将多个numpy数组拼接成一个数组–组合操作
假设现在我们有两三个数组都是需要进行同一个操作,当然你可以用个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)) # 输出为<class 'numpy.ndarray'> print(type(b)) # 输出为<class 'list'>
-
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 位浮点数(实数部分和虚数部分)
-
numpy常用函数
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.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
名句分享:如果你想知道生命的意义,请你假设如果自己只剩一天的生命,自己最想做什么即可。