前言

Numpy库是python中一个非常重要的库,它提供了一个多维数组(ndarray)数据类型,以及关于多维数组的操作,NumPy 已经成为其他大数据和机器学习模块的基础。

如果不想安Numpy库的,而你的电脑里没有安装python语言的,我们可以使用Anaconda,Anaconda里包含了很多我们要用到的科学包,包括了panda,numpy等,Anaconda可以在它的官网下载,速度可能会较慢.

官网地址为:https://www.anaconda.com/

安装Anaconda的教程可以看这篇文章:https://blog.csdn.net/qq_39610888/article/details/80805356

如果想看视频的可以去b站看这个视频:https://www.bilibili.com/video/av23124018?from=search&seid=17113017816135374394

安装完,我们就能在anaconda自带的juptyer里写代码了.

numpy的数组属性

在使用numpy我们需要像java一样,先进行导包

import numpy as np

numpy我们数组创建的常规创建方法

array=np.array([[1,2,3],
[4,5,6],
[7,8,9]])

print(array)

输出结果

[[1 2 3]
[4 5 6]
[7 8 9]]

这里我们的第一个array数组就创建好了.

我们可以使用numpy里的基本属性来获取我们新建数组的一些信息

ndarray.ndim

NumPy 数组的维数称为秩(rank),一维数组的秩为 1,二维数组的秩为 2,以此类推。

print(array.ndim)

ndarray.ndim 用于返回数组的维数,等于秩。

输出结果为:

2

ndarray.shape

表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。比如,一个二维数组,其维度表示"行数"和"列数"。

ndarray.shape 也可以用于调整数组大小。

print(array.shape)#代表矩阵的维度

输出结果为:

(3, 3)

ndarray.size

数组元素的总个数,相当于 .shape 中 n*m 的值

print(array.size)#代表数组元素的总个数

输出结果为:

9

ndarray.dtype

ndarray 对象的元素类型

print(array.dtype)#代表矩阵中元素的属性

输出结果为:

int32

numpy的数据类型

numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型。

创建array的方法

numpy.zeros

创建指定大小的数组,数组元素以 0 来填充:

import numpy as np
zero=np.zeros((2,3))#生成2行3列全为0的矩阵
print(zero)

输出结果为:

[[0. 0. 0.]
[0. 0. 0.]]

numpy.ones

创建指定形状的数组,数组元素以 1 来填充:

import numpy as np
one=np.ones((3,4))#生成3行4列全为1的矩阵
print(one)

输出结果为:

[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]

numpy.empty

numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:

import numpy as np
empty=np.empty((3,2))#生成3行2列全都接近0(不等于0)的矩阵
print(empty)

输出结果为:

[[0. 0.]
[0. 0.]
[0. 0.]]

numpy.arange

numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,函数格式如下:

numpy.arange(start, stop, step, dtype)

根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。

参数说明:

参数 描述
start 起始值,默认为0
stop 终止值(不包含)
step 步长,默认为1
dtype 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。

实例

生成 0 到 9 的数组:

import numpy as np
e=np.arange(10)
print(e)

输出结果如下:

[0 1 2 3 4 5 6 7 8 9]

生成 4到 11 的数组:

import numpy as np
f=np.arange(4,12)
print(f)

输出结果如下:

[ 4  5  6  7  8  9 10 11]

生成 1到 19 (每生成一个数字间隔3个数字)的数组:

import numpy as np
g=np.arange(1,20,3)
print(g)

输出结果如下:

[ 1  4  7 10 13 16 19]

Numpy 数组操作

修改数组形状

numpy.reshape

numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下:

numpy.reshape(arr, newshape, order=‘C’)

  • arr:要修改形状的数组
  • newshape:整数或者整数数组,新的形状应当兼容原有形状
  • order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
import numpy as np
h=np.arange(8).reshape(4,2)#重新定义矩阵的形状
print(h)

输出结果如下:

[[0 1]
[2 3]
[4 5]
[6 7]]

翻转数组

numpy.transpose

numpy.transpose 函数用于对换数组的维度,格式如下:

numpy.transpose(arr, axes)
  • arr:要操作的数组
  • axes:整数列表,对应维度,通常所有维度都会对换。

实例

import numpy as np

a = np.arange(12).reshape(3,4)

print ('原数组:')
print (a )
print ('\n')

print ('对换数组:')
print (np.transpose(a))

输出结果如下:

原数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]


对换数组:
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]

ndarray.T

一维数组不能转置

import numpy as np
arr1=np.array([1,2,3])
arr1.T
print(arr1)#一维的array不能转置

输出结果如下:

[1 2 3]

numpy.ndarray.T 类似 numpy.transpose

import numpy as np

a = np.arange(12).reshape(3,4)

print ('原数组:')
print (a)
print ('\n')

print ('转置数组:')
print (a.T)

输出结果如下:

原数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]


转置数组:
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]

改变维度

使用np.newaxis()函数

例子:

import numpy as np
arr1=np.array([1,2,3])
arr_1=arr1[np.newaxis,:]#改变维度,在行这里添加一个维度,使其变成1行3列
print(arr_1)
print(arr_1.shape)

输出结果如下:

[[1 2 3]]
(1, 3)
import numpy as np
arr1=np.array([1,2,3])
arr_2=arr1[:,np.newaxis]#在列这里添加一个维度,使其变成3行1列
print(arr_2)
print(arr_2.shape)

输出结果如下:

[[1]
[2]
[3]]
(3, 1)

使用

例子:np.atleast_2d()和np.atleast_3d()函数

print(arr1)#原数据,arr1是一维数据
arr_31=np.atleast_2d(arr1)#把arr1变成二维数据
arr_32=np.atleast_3d(arr1)#把arr1变成三维数据

print(arr_31)
print(arr_32)

print(arr_31.T)#二维数据转置
print(arr_32.T)#三维数据转置

输出结果如下:

[1 2 3]

[[1 2 3]]

[[[1]
[2]
[3]]]

[[1]
[2]
[3]]

[[[1]
[2]
[3]]]

numpy的基本运算

先创建数组

import numpy as np
arr1=np.array([[1,2,3],
[4,5,6]])
arr2=np.array([[1,1,2],
[2,3,3]])
print(arr1)
print(arr2)

输出结果如下:

[[1 2 3]
[4 5 6]]
[[1 1 2]
[2 3 3]]

加法

print(arr1+arr2)

输出结果如下:

[[2 3 5]
[6 8 9]]

减法

print(arr1-arr2)

输出结果如下:

[[0 1 1]
[2 2 3]]

乘法

print(arr1*arr2)

输出结果如下:

[[ 1  2  6]
[ 8 15 18]]

次方

print(arr1**arr2)

输出结果如下:

[[  1   2   9]
[ 16 125 216]]

相除

print(arr1/arr2)

输出结果如下:

[[1.         2.         1.5       ]
[2. 1.66666667 2. ]]

求余

print(arr1%arr2)

输出结果如下:

[[0 0 1]
[0 2 0]]

整除

print(arr1//arr2)

输出结果如下:

[[1 2 1]
[2 1 2]]

整体加

print(arr1+2)#所有的元素都加2

输出结果如下:

[[3 4 5]
[6 7 8]]

整体乘

print(arr1*10)#所有的元素都乘以10

输出结果如下:

[[10 20 30]
[40 50 60]]

判断大小

arr3=arr1>3#判断那个元素大于3
print(arr3)

输出结果如下:

[[False False False]
[ True True True]]

numpy.dot()

numpy.dot() 对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为内积);对于二维数组,计算的是两个数组的矩阵乘积;对于多维数组,它的通用计算公式如下,即结果数组中的每个元素都是:数组a的最后一维上的所有元素与数组b的倒数第二位上的所有元素的乘积和: dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

先定义一个arr4

import numpy as np
arr4=np.ones((3,5))
print(arr4)

输出结果如下:

[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
np.dot(arr1,arr4)#矩阵乘法

输出结果如下:

array([[ 6.,  6.,  6.,  6.,  6.],
[15., 15., 15., 15., 15.]])

对于矩阵乘法忘记了的或者了解不深的可以看这篇文章:https://www.cnblogs.com/alantu2018/p/8528299.html

随机数生成及矩阵的运算

np.random.random()函数

import numpy as np
samolel=np.random.random((3,2))#生成3行2列的随机数,范围(0-1)
print(samolel)

输出结果如下:

[[0.6150121  0.59427834]
[0.58806337 0.892053 ]
[0.59315305 0.92415359]]

numpy.random.standard_normal()函数用法

import numpy as np
samole2=np.random.normal(size=(3,2))#生成3行2列的随机数,符合标准正态分布
print(samole2)

输出结果如下:

[[ 0.36192863 -0.30079782]
[ 0.21587959 -0.15799396]
[-0.87615964 1.23683354]]

矩阵的运算

对于矩阵进行求和

np.sum(samolel)#对于samolel中的元素进行求和

输出结果如下:

4.206713449491107

对矩阵中的列进行求和

np.sum(samolel,axis=0)#当axis=0时是对于列,axis=1对于行,在这里是对列求和

输出结果如下:

array([1.79622852, 2.41048493])

对矩阵中的列进行行求和

np.sum(samolel,axis=1)#在这里是对行求和

输出结果如下:

array([1.20929044, 1.48011637, 1.51730664])

提取矩阵中的最小值

np.min(samolel)#提取samolel中的最小值

输出结果如下:

0.5880633706006644

提取矩阵中的最大值

np.max(samolel)#提取samolel中的最大值

输出结果如下:

0.9241535872093841

求矩阵中的平均值

print(np.mean(samolel))#求所有元素的平均值
print(samolel.mean())

输出结果如下:

0.7011189082485179
0.7011189082485179

求矩阵中的中位数

np.median(samolel)#求所有元素的中位数

输出结果如下:

0.6046452201028809

对于矩阵的数组就行开方

np.sqrt(samolel)#开方

输出结果如下:

array([[0.78422707, 0.77089451],
[0.7668529 , 0.94448558],
[0.7701643 , 0.96132907]])

对于矩阵的进行排序

np.sort(samolel)#排序

输出结果如下:

array([[0.39407608, 0.72871605],
[0.48484466, 0.73652244],
[0.19709554, 0.44424115]])

生成1行10列从1到10的随机数

import numpy as np
samole4=np.random.randint(0,10,size=(1,10))
print(samole4)

输出结果如下:

[[4 1 3 1 3 9 8 2 3 0]]

对于samole4使用np.clip()函数

np.clip(samole4,2,7)#小于2的元素变成2,大于7的元素变成7

输出结果如下:

array([[7, 7, 2, 6, 2, 5, 2, 5, 7, 6]])

np.clip()函数

numpy.clip(a, a_min, a_max, out=None)

  • 参数说明
  • a : 输入的数组
  • a_min: 限定的最小值 也可以是数组 如果为数组时 shape必须和a一样
  • a_max:限定的最大值 也可以是数组 shape和a一样
  • out:剪裁后的数组存入的数组

numpy的索引和切片,合并

索引

一维数组的索引

先新建一个array数组

import numpy as np
arr1=np.arange(2,14)
print(arr1)

输出结果如下:

[ 2  3  4  5  6  7  8  9 10 11 12 13]

获取位置在2的数据

print(arr1[2])#第二个位置的数据

输出结果如下:

4

获取第一到第三个位置的数据

print(arr1[1:4])#第一到第三个位置的数据,【1:4】不会包括4

输出结果如下:

[3 4 5]

获取第二个到倒数第一个位置的数据

print(arr1[2:-1])#第二到倒数第一个位置的数据

输出结果如下:

[ 4  5  6  7  8  9 10 11 12]

获取前5个数据

print(arr1[:5])#前5个数据

输出结果如下:

[2 3 4 5 6]

获取最后两个数据

print(arr1[-2:])#取最后两个数据

输出结果如下:

[12 13]

二维数组的索引

把之前的一维数组变为二维数组

arr2=arr1.reshape(3,4)
print(arr2)

输出结果如下:

[[ 2  3  4  5]
[ 6 7 8 9]
[10 11 12 13]]

获取第一行数据

对于一维数组而言,索引[1]是获取第一位的数据,而对于二维数组索引[1]是获取第一行的数据

print(arr2[1])#第一行

输出结果如下:

[6 7 8 9]

想要获取一个数据的话就要写清在二维数组的某一行某一列

例如:

获取第一行第一列的数据

print(arr2[[1][1])#第一行的第一列

输出结果如下:

7

获取第一行第二列的数据

print(arr2[1,2])#第一行的第二列

输出结果如下:

8

获取所有行的第二列

print(arr2[:,2])#所有行的第二列

输出结果如下:

[ 4  8 12]

切片

新建一个数组

import numpy as np
arr1=np.arange(12).reshape(3,4)
print(arr1)

输出结果如下:

[[ 0  1  2  3]
[ 4 5 6 7]
[ 8 9 10 11]]

按列切片

arr2,arr3=np.split(arr1,2,axis=1)#按列方向分割,分成2份
print(arr2)
print(arr3)

输出结果如下:

[[0 1]
[4 5]
[8 9]]
[[ 2 3]
[ 6 7]
[10 11]]

按行切片

arr4,arr5,arr6=np.split(arr1,3,axis=0)#按行方向分割,分成3份
print(arr4)
print(arr5)
print(arr6)

输出结果如下:

[[0 1 2 3]]
[[4 5 6 7]]
[[ 8 9 10 11]]

可能报错的地方

但是如果我们本身的数组,无法在我们的要求下进行切片会报错

例如:

arr2,arr3,arr4=np.split(arr1,3,axis=1)#按列方向分割,分成3份
print(arr2)
print(arr3)
print(arr4)

输出结果如下:

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
C:\ProgramData\Anaconda3\lib\site-packages\numpy\lib\shape_base.py in split(ary, indices_or_sections, axis)
842 try:
--> 843 len(indices_or_sections)
844 except TypeError:

TypeError: object of type 'int' has no len()

During handling of the above exception, another exception occurred:

ValueError Traceback (most recent call last)
<ipython-input-6-62c15d9e9149> in <module>
----> 1 arr2,arr3,arr4=np.split(arr1,3,axis=1)#按列方向分割,分成2份
2 print(arr2)
3 print(arr3)
4 print(arr4)

C:\ProgramData\Anaconda3\lib\site-packages\numpy\lib\shape_base.py in split(ary, indices_or_sections, axis)
847 if N % sections:
848 raise ValueError(
--> 849 'array split does not result in an equal division')
850 res = array_split(ary, indices_or_sections, axis)
851 return res

ValueError: array split does not result in an equal division

这就是本身数组无法被切分为3份,所以报错了

而我们一定要把arr1切分为3份的话,我们可以使用np.array_split()函数

arr7,arr8,arr9=np.array_split(arr1,3,axis=1)#按列分割,分成3份,不等分
print(arr7)
print(arr8)
print(arr9)

输出结果如下:

[[0 1]
[4 5]
[8 9]]
[[ 2]
[ 6]
[10]]
[[ 3]
[ 7]
[11]]

这样arr1会被强制切分为3份

其他切分方法

vsplit和hsplit

arrv1,arrv2,arrv3=np.vsplit(arr1,3)#按行分割
print(arrv1)
print(arrv2)
print(arrv3)

输出结果如下:

[[0 1 2 3]]
[[4 5 6 7]]
[[ 8 9 10 11]]
arrh1,arrh2=np.hsplit(arr1,2)#按列分割
print(arrh1)
print(arrh2)

输出结果如下:

[[0 1]
[4 5]
[8 9]]
[[ 2 3]
[ 6 7]
[10 11]]

合并

先新建数组

行合并

import numpy as np
arr1=np.array([1,2,3])
arr2=np.array([4,5,6])
arr3=np.vstack((arr1,arr2))#行合并
print(arr3)
print(arr3.shape)

输出结果如下:

[[1 2 3]
[4 5 6]]
(2, 3)

列合并

arr4=np.hstack((arr1,arr2))#列合并
print(arr4)
print(arr4.shape)

输出结果如下:

[1 2 3 4 5 6]
(6,)

也可以使用concatenate()函数合并

arr=np.concatenate((arr1,arr2,arr1))
print(arr)

输出结果如下:

[1 2 3 4 5 6 1 2 3]

但是注意使用concatenate()函数合并,array数组的维度要相同,array的形状要匹配

numpy数组的迭代

新建一个数组

import numpy as np
arr=np.random.randint(0,20,size=(3,4))
print(arr)

输出结果如下:

[[ 2  3  4  5]
[ 6 7 8 9]
[10 11 12 13]]

对于arr数组进行迭代行

for i in arr:#迭代行
print(i)

输出结果如下:

[2 3 4 5]
[6 7 8 9]
[10 11 12 13]

对于arr数组进行迭代列

for i in arr.T:#使用转置,来迭代列
print(i)

输出结果如下:

[ 2  6 10]
[ 3 7 11]
[ 4 8 12]
[ 5 9 13]

对于arr数组一个一个元素进行迭代

for i in arr2.flat:#一个一个元素的迭代
print(i)

输出结果如下:

2
3
4
5
6
7
8
9
10
11
12
13

numpy的浅拷贝和深拷贝

直接上例子

import numpy as np
a=np.array([1,2,3])
b=arr1 #arr1和arr2共享一块内存,浅拷贝
b[0]=5
print(a)
print(b)

输出结果如下:

[5 2 3]
[5 2 3]

可以看到,改变a后,b的值也跟着变了,这是为什么呢?

实际上,变量a中并没有存储任何的值,它只是指向了一个内存地址,而这个地址里存储着array具体的内容,当把a赋值给b的时候,实际上是把a指向内存中某对象的链接赋给了b,也就是说,现在a和b都指向了同一个对象。

因此,在改变了内存中array的值后,而a与b都引用了该array对象,所以都一起发生了变化

这种将内存引用赋值给另一个变量的操作叫做浅拷贝

c=a.copy()#深拷贝
c[0]=10

print(a)
print(c)


输出结果如下:

[5 2 3]
[10 2 3]
a引用的对象的地址: 2130290221504
c引用的对象的地址: 2130290057088

深拷贝呢,其实就是在赋值的时候,不把同一个内存对象的引用赋值给另一个变量,令两个变量所指向的对象不一样,更改值的时候不相互影响,这种操作就是深拷贝

copy()会创建a的一个副本,也就是创建一个一模一样的array对象,存储到内存的另一个地址中,然后将这个副本的地址赋值给c

目前我对于numpy库的学习到这里也就结束了,当后面学的更深入的时候,可能还会更新,本文写的可能不是很好,但还是感谢大家的阅读