python数据科学库numpy如何使用
目录
import numpy as np
为什么使用numpy
- python自带list使用不方便,运行缓慢;
- numpy是python的计算拓展库,开源,集成了一系列已编译的数学和矩阵计算函数;
- numpy有独有的数据结构,使用方便,运行快速;
- numpy数据占用空间小,读取速度快。
numpy矩阵的创建以及数据类型
生成的类型为 numpy.ndarray,数据是线性的且连续存储。
直接使用np.array创建
a = np.array([1, 2, 3])
使用numpy函数
np.arange()、np.linspace()
'''
np.arange([start,] stop[, step,], dtype = None)
'''
>>> np.arange(1, 5)
array([1, 2, 3, 4])
'''
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)
返回间隔均匀的数组
'''
# 生成了[0, 10]十一等分数据
>>> np.linspace(0, 10, 11)
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
np.zeros() 、np.ones()、np.eye()
>>> np.zeros((3, 4))
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
>>> np.ones((3, 4))
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
>>> np.eye(4) # 对角矩阵
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
np.empty()、np.zeros_like()、np.ones_like()
'''
numpy.empty(shape, dtype=float, order='C')
返回shape形状的空矩阵
'''
>>> b = np.empty((3, 4))
>>> b
array([[6.89796323e-307, 2.78148153e-307, 2.78144588e-307,
1.60219035e-306],
[4.45064003e-308, 1.24611741e-306, 1.60219035e-306,
4.22791195e-307],
[3.44900369e-307, 4.00536722e-307, 2.33646845e-307,
4.00540457e-307]])
'''
numpy.zeros_like(a, dtype=None, order='K', subok=True, shape=None)
返回和a矩阵形状一样的零矩阵
'''
>>> np.zeros_like(b)
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
'''
numpy.ones_like(a, dtype=None, order='K', subok=True, shape=None)
返回和a矩阵形状一样的1矩阵
'''
>>> np.ones_like(b)
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
矩阵形状
numpy.shape,numpy.reshape()的运用。
# 矩阵的维度
>>> g = np.array([1, 2, 3], [4, 5, 6])
>>> g.shape
(2, 3)
>>> h = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
>>> h.shape
(2, 2, 3)
# 修改矩阵的形状, 注意矩阵中的元素个数是相同的,2 * 2 * 3 = 2 * 6
# 当不知道具体矩阵的维度时,可以通过shape来获取,h.shape[0], h.shape[1]
>>> h.reshape((2, 6))
array([[ 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12]])
>>> h
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
'''
注意reshape修改并未改变原来的矩阵,只是返回了一个新的值!
'''
# 将一个多维数组按行展开
>>> h.flatten()
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
数据类型
numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上。常用Numpy数据类型可见此。
使用dtype可以查看numpy数据的类型。
'''
numpy.dtype(object, align, copy)
object: 要转换为的数据类型对象
align: 如果为 true,填充字段使其类似 C 的结构体。
copy: 复制 dtype 对象, 如果为 false,则是对内置数据类型对象的引用
所输出的类型后的数字,若没有修改,代表的是该数据的默认位数,
默认指定的位数考虑到了效率与便捷问题,一般是比较通用的情况,可以自行修改
'''
>>> b = np.arange(1, 5)
>>> b.dtype
dtype('int32')
>>> c = np.array(range(1, 6), dtype = float)
>>> c.dtype
dtype('float64')
>>> d = np.array(range(1, 6), dtype = "i1")
>>> d.dtype
dtype('int8')
'''
调整数据类型
'''
# eg: int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替
>>> e = d.astype("int8")
>>> e.dtype
dtype('int8')
# 取小数操作
>>> f = np.array([random.random() for i in range(7)])
>>> np.round(f, 2)
array([0.73, 0.92, 0.33, 0.77, 0.67, 0.98, 0.48])
numpy矩阵的计算
广播原则
python的广播原则:
如果两个数组的后缘维度(trailing dimension),即从末尾开始算起的维度的轴长度相符或其中一方的长度为1则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
eg: shape为(1, 2, 3)的矩阵
- 其可以和shape为(3)的矩阵计算,在第一维度和第二维度上进行;
- 其可和shape为(2, 3)的矩阵计算,在第一维度上进行;
- 其不可和shape为(2, 4)的矩阵计算。
具体编程示例如下:
数字计算
# python numpy计算的广播机制,整体变化
>>> i = np.arange(1, 13)
>>> i = i.reshape((3, 4))
>>> i
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> i + 3
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> i * 2
array([[ 2, 4, 6, 8],
[10, 12, 14, 16],
[18, 20, 22, 24]])
>>> j = i - 1
>>> j
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> j / 0
array([[nan, inf, inf, inf],
[inf, inf, inf, inf],
[inf, inf, inf, inf]])
'''
此时python提示warning,但是仍然可以计算,nan表示不是一个数字,inf表示无穷大
'''
矩阵计算
# 矩阵计算,注意维度问题
'''
example 1
'''
>>> i + j
array([[ 1, 3, 5, 7],
[ 9, 11, 13, 15],
[17, 19, 21, 23]])
>>> i * j
array([[ 0, 2, 6, 12],
[ 20, 30, 42, 56],
[ 72, 90, 110, 132]])
'''
example 2-1
当其中某个为一维的时候,即这个维度不相等,此时也可计算, 但必须保证另一个维度相等
'''
>>> i
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> k = np.arange(1, 5)
>>> k
array([1, 2, 3, 4])
>>> i * k # 其中i形状为(3, 4), k为(1, 4), 满足广播原则
array([[ 1, 4, 9, 16],
[ 5, 12, 21, 32],
[ 9, 20, 33, 48]])
>>> i + k
array([[ 2, 4, 6, 8],
[ 6, 8, 10, 12],
[10, 12, 14, 16]])
'''
example 2-2
'''
>>> l = np.array([[1], [2], [3]])
>>> l
array([[1],
[2],
[3]])
>>> i + l # i形状为(3, 4), l的形状为(3, 1), 长度为1, 满足广播机制
array([[ 2, 3, 4, 5],
[ 7, 8, 9, 10],
[12, 13, 14, 15]])
>>> i * l
array([[ 1, 2, 3, 4],
[10, 12, 14, 16],
[27, 30, 33, 36]])
'''
example 3
'''
>>> a = np.arange(18).reshape(3, 3, 2)
>>> b = np.arange(9).reshape(3, 3)
>>> a
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15],
[16, 17]]])
>>> b
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> a + b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (3,3,2) (3,3)
'''
出现报错!
不满足广播机制,(3, 3, 2)与(3, 3)的矩阵不能够进行运算!
'''
'''
当b修改为如下时(3, 3, 1)即可进行运算!(3, 3, 2)与(3, 3, 1)
'''
>>> b = np.arange(9).reshape(3, 3, 1)
>>> b
array([[[0],
[1],
[2]],
[[3],
[4],
[5]],
[[6],
[7],
[8]]])
>>> a + b
array([[[ 0, 1],
[ 3, 4],
[ 6, 7]],
[[ 9, 10],
[12, 13],
[15, 16]],
[[18, 19],
[21, 22],
[24, 25]]])
numpy中矩阵转置
a = np.arange(12).reshape((3, 4))
# 法一:
a.transponse()
# 法二:
a.T
# 法三:交换轴
a.swapaxes(1, 0)
numpy的切片、索引
>>> a = np.arange(12).reshape((3, 4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a[1:3] # 取行
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a[:, 2:4] # 取列
array([[ 2, 3],
[ 6, 7],
[10, 11]])
>>> a[[0, 2]] # 不连续的多行
array([[ 0, 1, 2, 3],
[ 8, 9, 10, 11]])
>>> a[[0, 2], [1, 3]] # 多个点
array([ 1, 11])
'''
注意虽然取的是整数,但是并不是之前的int32类型
'''
>>> type(a[1, 2])
<class 'numpy.int32'>
numpy中的数字的寻找与替换
>>> a = np.arange(12).reshape((3, 4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a < 5
array([[ True, True, True, True],
[ True, False, False, False],
[False, False, False, False]])
'''
法一:使用逻辑判断True和False,将a矩阵中所有小于5的数替换为6
'''
>>> a[a < 5] = 6
>>> a
array([[ 6, 6, 6, 6],
[ 6, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a = np.arange(12).reshape((3, 4))
>>> a[a < 5] # 注意区分这个和上面赋值
array([0, 1, 2, 3, 4])
'''
法二:使用where函数
numpy.where(condition[, x, y])
根据条件返回从x或y中选择的元素
'''
# 将矩阵a中所有小于5的数替换为6,大于5的数替换为1
>>> np.where(a < 5, 6, 1)
array([[6, 6, 6, 6],
[6, 1, 1, 1],
[1, 1, 1, 1]])
'''
法三:使用clip函数
numpy.clip(a, a_min, a_max, out=None, **kwargs)
给定一个区间,区间外的值被裁剪到区间的边界上,
举例来说,给定区间[a, b],大于b的变成b,小于a的变成a
'''
# numpy中的clip,大于8的变为8,小于5的变成5
>>> a.clip(5, 8)
array([[5, 5, 5, 5],
[5, 5, 6, 7],
[8, 8, 8, 8]])
'''
numpy矩阵含有inf、nan的类型转换
'''
>>> a[2, 3] = np.nan
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot convert float NaN to integer
# 需要对numpy矩阵类型进行转换,如下即可
>>> a = a.astype(float)
>>> a
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
>>> a[2, 3] = np.nan
>>> a
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., nan]])
矩阵的拼接
>>> a = np.arange(12).reshape((3, 4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b = np.arange(12, 24).reshape((3, 4))
>>> b
array([[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
'''
竖直拼接,注意竖直分割是这个方向
'''
>>> np.vstack((a, b))
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]])
'''
水平拼接,注意水平分割是这个方向
'''
>>> np.hstack((a, b))
array([[ 0, 1, 2, 3, 12, 13, 14, 15],
[ 4, 5, 6, 7, 16, 17, 18, 19],
[ 8, 9, 10, 11, 20, 21, 22, 23]])
矩阵的行列交换
>>> a = np.arange(12).reshape((3, 4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 行交换
>>> a[[0, 1], :] = a[[1, 0], :]
>>> a
array([[ 4, 5, 6, 7],
[ 0, 1, 2, 3],
[ 8, 9, 10, 11]])
# 列交换
>>> a[:, [0, 1]] = a[:, [1, 0]]
>>> a
array([[ 5, 4, 6, 7],
[ 1, 0, 2, 3],
[ 9, 8, 10, 11]])
使用argmin与argmax获取矩阵中最大最小值
>>> c = np.array([random.randint(1, 100) for i in range(12)]).reshape((3, 4))
>>> c
array([[ 66, 100, 19, 48],
[ 95, 68, 81, 9],
[ 60, 80, 12, 63]])
'''
获取最大值位置
'''
>>> np.argmax(c) # 相当于数组为一维的时索引
1
>>> np.argmax(c, axis = 0) # 取的为每一列的最大值
array([1, 0, 1, 2], dtype=int64)
'''
获取最小值位置
'''
>>> np.argmin(c) # 相当于数组为一维的时索引
7
>>> np.argmin(c, axis = 1) # 取得为每一行的最小值
array([2, 3, 2], dtype=int64)
numpy生成随机数
参数 | 说明 |
---|---|
.rand(d0, d1, …, dn) | 创建d0—dn维度的均匀分布的随机数数组,范围为[0, 1),浮点数 |
.randn(d0, d1, …, dn) | 创建d0—dn维度、满足均值为0、方差为1的标准正态分布随机数数组,未给定参数的情况下,返回从分布中随机采样的单个浮点数 |
.randint(low, high=None, size=None, dtype=int) | 从指定dtype的离散均匀分布[low, high)中返回随机整数,如果没有指定high,默认区间为[0, low) |
.uniform(low=0.0, high=1.0, size=None) | 样本均匀分布在区间[low, high),从其中抽取样本 |
.normal(loc=0.0, scale=1.0, size=None) | 从正态分布中抽取随机样本,loc为均值,scale为标准差 |
.seed(self, seed=None) | 随机数种子,seed是给定的种子值,通过设定相同的随机数种子,可以每次生成相同的随机数(计算机生成的是伪随机数) |
>>> np.random.rand(3,4)
array([[0.6350389 , 0.42583308, 0.83244198, 0.13534336],
[0.1646268 , 0.08109012, 0.31921804, 0.58858143],
[0.16737554, 0.22531111, 0.89541298, 0.35630342]])
随机数种子
import numpy as np
i = 0
while i < 5:
np.random.seed(3)
print(np.random.rand(1, 2))
i = i + 1
上述代码输出为:
[[0.5507979 0.70814782]]
[[0.5507979 0.70814782]]
[[0.5507979 0.70814782]]
[[0.5507979 0.70814782]]
[[0.5507979 0.70814782]]
对代码修改如下:
import numpy as np
i = 0
np.random.seed(3)
while i < 5:
print(np.random.rand(1, 2))
i = i + 1
输出为:
[[0.5507979 0.70814782]]
[[0.29090474 0.51082761]]
[[0.89294695 0.89629309]]
[[0.12558531 0.20724288]]
[[0.0514672 0.44080984]]
两者的区别在于随机数种子的设置位置不同,随机数种子设置一定的时候,产生的随机数一样,但后者是将随机数种子的设置放到了循环之外,使得除第一次循环之外,其余的军事重新生成的随机数种子,于是生成的每次结果均不相同。
numpy中的nan与inf
nan与inf
nan(not a number):表示并非一个数字,它和任何值计算的结果都是nan,典型出现情况如下:
- 当计算不恰当时(如0/0,且结果不为inf/-inf),则会出现nan;
- 当读取本地float文件出现缺失时
inf(infinity / - infinity):无穷大(正负),出现典型情况是非0的数a除以0,其出现在python中会直接报错,如下:
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
注意 np,inf 与 np.nan 均为float类型
# 两个np.nan不相等
>>> np.nan == np.nan
False
判断矩阵中有多少个nan
'''
法一:可以利用numpy中count_nonzero函数来判断矩阵中有几个nan
numpy.count_nonzero(a, axis=None, *, keepdims=False)
对数组a中的非零值进行计数
'''
>>> a
array([[ 5., 4., 6., 7.],
[ 1., 0., nan, 3.],
[ 9., nan, 10., 11.]])
>>> a != a
array([[False, False, False, False],
[False, False, True, False],
[False, True, False, False]])
>>> np.count_nonzero(a != a)
2
'''
法二:利用np.isnan()函数
numpy.isnan(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) = <ufunc 'isnan'>
测试数组中是否有元素nan,并以布尔数组的形式返回结果
'''
>>> np.isnan(a)
array([[False, False, False, False],
[False, False, True, False],
[False, True, False, False]])
>>> np.count_nonzero(np.isnan(a))
2
'''
nan和任何值作计算,结果均为nan
'''
>>> a
array([[ 5., 4., 6., 7.],
[ 1., 0., nan, 3.],
[ 9., nan, 10., 11.]])
>>> np.sum(a)
nan
>>> np.sum(a, axis = 0)
array([15., nan, nan, 21.])
>>> np.sum(a, axis = 1)
array([22., nan, nan])
nan的替换
nan在读取数据中通常是缺失值,一般把nan替换为均值,或者是直接删除有nan的那一行/列。
numpy中常用统计函数
函数 | 功能 |
---|---|
np.sum(a) 、a.sum() | 求和 |
np.mean(a)、a.mean() | 均值 |
np.median(a) | 中值 |
np.max(a)、a.max() | 最大值 |
np.min(a)、a.min() | 最小值 |
np.ptp(a)、a.ptp() | 极值 |
np.std(a)、a.std() | 标准差 |
numpy读取数据
分析数据的思路:看到这个问题,我们应该怎么思考?
- 想要得出什么结论,解决什么问题?
- 选择什么样的呈现方式?
- 数据还需要做什么样的处理?
- 编写代码
numpy.loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes', max_rows=None)
参数含义如下:
参数 | 解释 |
---|---|
frame | 需要读取的文件 |
dtype | 读取数组的数据类型,默认为浮点数 |
comments | 用来表示注释开始的字符,默认为# |
delimiter | 用于分隔值的字符串,默认为空格 |
skiprows | 跳过几行开始读数,包括注释 |
usecols | 要读取的列,第一列为0,默认值为None,读取所有 |
unpack | 如果为True,返回的数组将会被转置,便于将属性分别写入不同的数组变量,默认为False,仅仅写入一个数组变量 |
ndmin | 返回的数组至少有ndmin维度,否则,一维轴将被压缩,值可取0(默认值),1,2 |
encoding | 用于解码输入文件的编码,默认为bytes |
max_rows | 从跳过行数之后开始,读取的最多行数,默认情况下读取所有行 |
(等有时间可以整理更完善些。)
参考资料
- https://numpy.org/doc/stable/reference/generated/numpy.isnan.html?highlight=isnan#numpy.isnan
- https://*.com/questions/41774047/using-numpy-to-square-value-gives-negative-number
- https://www.runoob.com/numpy/numpy-dtype.html
- 视频教程
本文地址:https://blog.csdn.net/TXY_xy/article/details/111055369
上一篇: git常用命令大全(超详细)
下一篇: NameNode之文件系统目录树介绍
推荐阅读
-
使用wordpress的$wpdb类读mysql数据库做ajax时出现的问题该如何解决
-
利用Python如何批量修改数据库执行Sql文件
-
在python操作数据库中游标的使用方法
-
python数据库操作常用功能使用详解(创建表/插入数据/获取数据)
-
Windows7下Python3.4使用MySQL数据库
-
Python使用Flask-SQLAlchemy连接数据库操作示例
-
python使用adbapi实现MySQL数据库的异步存储
-
python数据库-MongoDB的基本使用(54)
-
Python 使用数据库(SQLite)
-
使用python将mdb数据库文件导入postgresql数据库示例