Numpy基础知识点汇总

1、概述

Numpy是高性能科学计算和数据分析的基础包,它的部分功能如下: 1)ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组。 2)对整组数据进行快速运算的标准数学函数 3)用于读写磁盘数据的工具以及用于操作内存映射文件的工具。

2、ndarray的创建

这一节,我们主要关注ndarray数组的创建,我们主要有以下几种方式: 数组转换 创建数组的最简单的方法就是使用array函数,将Python下的list转换为ndarray。

#通过数组创建一个ndarray
data1 = [6,7.5,8,0,1]
arr1 = np.array(data1)
arr1

输出为:

array([ 6. ,  7.5,  8. ,  0. ,  1. ])

也可以创建二维数组

#通过数组创建一个二维的ndarray
data2 = [[1,2,3,4],[5,6,7,8]]
arr2 = np.array(data2)
arr2

输出为:

array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

数组生成 除了通过数组转换而来之外,我们可以利用np中的一些内置函数来创建数组,比如我们创建全0的数组,也可以创建全1数组,或者等差数列数组:

##创建全0数组
np.zeros(10)

输出为:

array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
np.ones(3)

输出为:

array([ 1.,  1.,  1.])
#创建等差数组
np.arange(1,15,2)

输出为:

array([ 1,  3,  5,  7,  9, 11, 13])

我们已可以生成一些随机数数组,比如下面的方式可以生成均值为2,标准差为3的正态分布数组:

#创建正态分布随机数数组
samples = np.random.normal(2,3,size=(4,4))
samples

输出为:

array([[ 3.22094168,  2.83535518,  6.08625335,  1.28604611],
       [ 1.28741059, -2.76328197,  3.04233101,  2.01606861],
       [-4.01262367, -1.12355259,  0.59416967,  4.07616321],
       [-1.9936047 ,  0.32834631,  5.64805711,  4.19171525]])

如果想生成标准正态分布随机数组,可以直接使用randn函数:

#创建正态分布数组
samples1 = np.random.randn(4,4)
samples

输出为:

array([[ 2.61680992,  1.72497013,  2.97738852,  0.78316473],
       [ 3.41222285,  3.50582899,  2.5927854 ,  5.09012117],
       [ 0.55369215,  6.66957866,  4.37837409,  5.25935515],
       [-0.82391358, -2.22526414,  0.2730311 ,  1.69091322]])

我们也可以使用randint生成随机整数数组,前两个参数决定了数组中数据的值的上下限:

#创建随机整数数组
draws = np.random.randint(0,10,size=(3,4))
draws

输出为:

array([[2, 2, 4, 5],
       [7, 5, 8, 5],
       [9, 0, 6, 1]])

文件读取 numpy还可以读取txt或者csv文件来创建ndarray,也可以读取从别的代码中保存的np文件,我们可以使用save方法保存ndarray到一个npy文件,也可以使用savez将多个array保存到一个.npz文件中:

x = np.array([1,2,4,5])
y = np.array([3,4,5])
#save方法可以存取一个ndarray
np.save("x_arr",x)
#如果要存取多个数组,要是用savez方法
np.savez("some_array.npz",xarr = x,yarr=y)

保存文件之后,我们可以通过load方法来读取存储的数组,如果是.npz文件的话,读取之后相当于形成了一个k-v类型的变量,通过保存时定义的key来获取相应的array。

np.load('x_arr.npy')
#array([1, 2, 4, 5])
arch = np.load("some_array.npz")
arch['yarr']
#array([3, 4, 5])

np.loadtxt 和 np.savetxt可以用来存取txt或csv文件:

arr = np.loadtxt('array_ex.txt',delimiter=',',dtype=np.int32)
arr
#array([[1, 2, 3, 4, 5],
#       [2, 3, 4, 5, 6],
#       [4, 5, 7, 8, 9]], dtype=int32)

np.savetxt("array_ex1.txt",arr)

3、ndarray的数据类型

ndarray的数据类型有int8、int16、int32、int64、float16、float32、float64等等,我们可以在创建数组时显式指定数据类型:

#指定array的数据类型
arr1 = np.array([1,2,3],dtype=np.int32)
arr2 = np.array([1,2,3],dtype=np.float32)

我们可以使用数组的dtype属性对数组的数据类型进行查看:

#查看array的数据类型
arr2.dtype
### dtype('float32')

我们可以使用astype将一个数组的数据类型进行转换,这样会返回一个新的数组,对原数组不会产生影响

#数据类型进行转换,会产生一个新的array,原array不产生影响
arr1.astype(np.float32)
arr1.dtype
# dtype('int32')

float_arr = arr1.astype(np.float32)
float_arr.dtype
# dtype('float32')

如果一个数组中的字符串只含有数字,可以将string转换为数值形式:

numeric_strings = np.array(['1.25','0.96','42'],dtype=np.string_)
numeric_strings.astype(np.float32)
# array([  1.25      ,   0.95999998,  42.        ], dtype=float32)

4、数组运算

大小相等的数组之间的任何算数运算都会应用到元素身上

arr = np.array([[1,2,3],[4,5,6]],dtype=np.float32)
arr * arr

#array([[  1.,   4.,   9.],
#       [ 16.,  25.,  36.]], dtype=float32)

arr - arr

#array([[ 0.,  0.,  0.],
 #      [ 0.,  0.,  0.]], dtype=float32)

数组与标量的算术运算也会将标量值传播到各个元素:

1 / arr

#array([[ 1.        ,  0.5       ,  0.33333334],
#       [ 0.25      ,  0.2       ,  0.16666667]], dtype=float32)

5、索引和切片

基本的索引和切片 numpy基本的索引和切片功能和Python列表的操作相似,不过要注意的是numpy中数组切片是原始数组的视图,这意味着数据不会被复制,视图上任何数据的修改都会反映到原数组上,因为numpy被设计用来处理大数据,如果切片不是视图而是复制产生新数据的话,会产生相应的性能和内存问题。如下面的例子,对切片的操作会影响原数组:

arr = np.arange(10)
arr[5]
# 5
arr[5:8]
#array([5, 6, 7])
arr[5:8]=12
t = arr[5:8]
t[1] = 12345
arr
#array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,     9])

如果你想得到复制的数据的话,使用copy方法,可以看到使用copy之后再修改数据不会影响到原数据:

t1 = arr[5:8].copy()
t1[2] = -222
arr

#array([ 0,  1,  2,  3,  4, 64, 64, 64,  8,  9])

对于二维数组或者高维数组,我们可以按照之前的知识来索引,当然也可以传入一个以逗号隔开的索引列表来选区单个或多个元素

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

arr2d[:2,1:]
#array([[2, 3],
#       [5, 6]])

布尔型索引

我们还可以使用布尔型的索引形式:

names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
data = np.random.randn(7,4)

names == 'Bob'
#array([ True, False, False,  True, False, False, False], dtype=bool)

data[names=='Bob']
#array([[ 0.75323688,  0.85622553, -2.71974541,  0.37865467],
#       [ 1.35356641,  0.09263267,  1.96207471, -0.05549953]])

在使用布尔型索引形式时,我们可以进行相应的逻辑运算,不过这里的或是一根竖线,与是一个&:

data[(names=='Bob')| (names=='Will')]

#array([[ 0.75323688,  0.85622553, -2.71974541,  0.37865467],
       [ 0.93720776, -1.49360063, -0.06471438,  0.62149438],
       [ 1.35356641,  0.09263267,  1.96207471, -0.05549953],
       [ 1.87344915,  1.75085643,  1.9197879 ,  0.47687361]])

花式索引

除基本的索引和切片外,numpy还提供了花式索引的方式,它指利用整数数组进行索引,花式索引和切片不一样,它总是将数据复制到新数组中:

arr = np.empty((8,4))
for i in range(8):
    arr[i] = i
arr[[4,3,0,6]]

上面的语句按4,3,0,6的顺序选取了数组中的四行,所以得到的结果为:

array([[ 4.,  4.,  4.,  4.],
       [ 3.,  3.,  3.,  3.],
       [ 0.,  0.,  0.,  0.],
       [ 6.,  6.,  6.,  6.]])

我们也可以使用负数从最后一行开始选取:

arr[[-3,-5,-7]]

如果我们想选择一块方形区域,同时按照我们指定的顺序排列数据,我们尝试以下的方式:

arr = np.arange(32).reshape((8,4))
arr[[1,5,7,2],[0,3,1,2]]

输出为:

array([ 4, 23, 29, 10])

这是因为按照上面的方式进行选取,会将选择出的元素锁定在4个元素上。 正确的方式有下面两种:

arr[[1,5,7,2]][:,[0,3,1,2]]
arr[np.ix_([1,5,7,2],[0,3,1,2])]

输出为:

array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])

6、数组转置和轴对换

数组的转置是重塑的一种特殊形式,它返回的事原数据的视图。不仅有transpose方法,还有特殊的T属性:

arr = np.arange(15).reshape((5,3))
arr.T

#array([[ 0,  3,  6,  9, 12],
       [ 1,  4,  7, 10, 13],
       [ 2,  5,  8, 11, 14]])

对于高维数组,tranpose需要得到一个由轴编号组成的元组才能对这些轴进行转置,太费脑子:

arr = np.arange(16).reshape((2,2,4))
arr

#array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

arr.transpose((1,0,2))
#array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

还可以使用swapaxes函数进行转置,它接受一对轴编号:

arr.swapaxes(1,2)

7、数组函数

通用函数:元素级数组函数 通用函数中,有一元的函数,如abs,sqrt,square,exp,log等等,也有二元的函数maximum、minimum等等,这些都比较简单,我们举两个例子即可:

arr = np.arange(10)
np.sqrt(arr)

x = np.random.randn(8)
y = np.random.randn(8)
np.maximum(x,y)
#array([ 0.68417031,  0.22971426,  1.69724546,  1.19366822, -0.79176777, -0.43557768,  0.66628223,  0.85093113])

where函数 where函数,三个参数,条件,条件为真时选择值的数组,条件为假时选择值的数组:

xarr = np.array([1.1,1.2,1.3,1.4,1.5])
yarr = np.array([2.1,2.2,2.3,2.4,2.5])
cond = np.array([True,False,True,True,False])
np.where(cond,xarr,yarr)

输出为:

array([ 1.1,  2.2,  1.3,  1.4,  2.5])

也可以使用下面的形式,后两个参数为指定值:

np.where(xarr>1.2,2,-2)
#array([-2, -2,  2,  2,  2])

数学和统计方法 数学和统计方法既可以当作数组的实例方法调用,也可以当作顶级numpy函数调用,比如下面两种计算数组均值的方法是等效的:

arr = np.random.randn(5,4)
arr.mean()
np.mean(arr)

mean或sum这一类函数可以接受一个axis参数,用于计算该轴向上的统计值,最终结果是一个少一维的数组。对于一个二维数组,axis=0相当于按列操作,最终元素的个数和第二维的大小相同,axis=1相当于按行操作,最终元素的个数和第一维的大小相同:

arr.mean(axis=1)
#array([ 0.29250253, -0.50119163,  0.11746254,  0.23338843,  0.15912472])

arr.sum(0)
#array([ 1.92728592,  0.67480797, -2.8398905 ,  1.44294295])

我们也可以用cumsum(累加值计算)和cumprod(累积值计算)保留中间计算结果:

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

#array([[ 1,  2,  3],
       [ 5,  7,  9],
       [12, 15, 18]])

arr.cumprod(1)
#array([[  1,   2,   6],
       [  4,  20, 120],
       [  7,  56, 504]])

排序方法 np中还提供了排序方法,排序方法是就地排序,即直接改变原数组:

arr = np.random.randn(8)
arr
#array([-0.85668922, -2.0049649 , -0.89885165, -0.04185277,  0.73736138,-0.03509021, -1.89745107, -2.36576122])

arr.sort()
arr
#array([-2.36576122, -2.0049649 , -1.89745107, -0.89885165, -0.85668922,-0.04185277, -0.03509021,  0.73736138])

集合运算函数 unique计算x中的唯一元素,并返回有序结果

arr = np.array([1,3,2,5,2,4,2,2,1,4,5,2])
np.unique(arr)
#array([1, 2, 3, 4, 5])

numpy提供了下面三个常见的集合运算函数: intersect1d(x,y) 用于计算x和y的公共结果,并返回有序结果 union1d(x,y) 用于计算x和y的并集,并返回有序结果 setdiff1d(x,y),集合的差,即元素在x中不在y中

x = np.array([1,2,4,5])
y = np.array([3,4,5])
np.intersect1d(x,y)
#array([4, 5])
np.union1d(x,y)
#array([1, 2, 3, 4, 5])
np.setdiff1d(x,y)
#array([1, 2])

8、线性代数

numpy还提供了许多线性代数运算的函数,比如计算矩阵的乘积:

#矩阵的乘积
x = np.array([[1,2,3],[4,5,6]])
y = np.array([[6,23],[-1,7],[8,9]])
np.dot(x,y)

下面可以计算矩阵的逆、行列式、特征值和特征向量、qr分解值,svd分解值:

#计算矩阵的逆
from numpy.linalg import inv,det,eig,qr,svd
t = np.array([[1,2,3],[2,3,4],[4,5,6]])
inv(t)

#计算矩阵行列式
det(t)

#计算QR分解址
qr(t)

#计算奇异值分解值svd
svd(t)

#计算特征值和特征向量
eig(t)

原文发布于微信公众号 - 小小挖掘机(wAIsjwj)

原文发表时间:2017-10-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

23:二维数组回形遍历

23:二维数组回形遍历 总时间限制: 1000ms 内存限制: 65536kB描述 给定一个row行col列的整数数组array,要求从array[0][0...

5096
来自专栏数据结构与算法

洛谷P3357 最长k可重线段集问题(费用流)

题目描述http://www.cnblogs.com/zwfymqz/p/8559566.html 给定平面 x-O-yx−O−y 上 nn 个开线段组成的集合...

4106
来自专栏ACM算法日常

字符串的距离(动态规划) - leetcode 72

,因为在刷leetcode的动态规划专题。动态规划虽然定义很简单,但是对于复杂的动态规划题目,很多时候还是很棘手的。

852
来自专栏小樱的经验随笔

洛谷 P1019 单词接龙【经典DFS,温习搜索】

P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”...

3816
来自专栏xingoo, 一个梦想做发明家的程序员

剑指OFFER之二维数组中的查找(九度OJ1384)

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组...

2237
来自专栏我的博客

C编程笔记

1.编译命令gcc test.c -o test 带上参数o就是指定编译文件名 2.printf(“%.2lf”,b) 其中前面2是小数点后位数,l是字母...

3695
来自专栏图像识别与深度学习

2018-07-02Python数组

1233
来自专栏java工会

java冒泡排序和快速排序

3053
来自专栏黑泽君的专栏

java基础学习_基础语法(下)02_day06总结

============================================================================= ==...

611
来自专栏伪君子的梦呓

leetcode 题解~两数之和 ~ C++做法

1775

扫码关注云+社区

领取腾讯云代金券