Numpy学习

前言

最近在DL里被各种矩阵计算虐得很渣,决定学习一波numpy

正文

1、先学习一下用numpy打开txt文件

import numpy

world_alcohol = numpy.genfromtxt("world_alcohol.txt",delimiter=",",dtype=str)
print(type(world_alcohol))
print(world_alcohol)
print(help(numpy.genfromtxt))

#
<class 'numpy.ndarray'>
[['Year' 'WHO region' 'Country' 'Beverage Types' 'Display Value']
 ['1986' 'Western Pacific' 'Viet Nam' 'Wine' '0']
 ['1986' 'Americas' 'Uruguay' 'Other' '0.5']
 ...
 ['1987' 'Africa' 'Malawi' 'Other' '0.75']
 ['1989' 'Americas' 'Bahamas' 'Wine' '1.5']
 ['1985' 'Africa' 'Malawi' 'Spirits' '0.31']]

txt内容如下:

Year,WHO region,Country,Beverage Types,Display Value
1986,Western Pacific,Viet Nam,Wine,0
1986,Americas,Uruguay,Other,0.5
1985,Africa,Cte d'Ivoire,Wine,1.62
1986,Americas,Colombia,Beer,4.27
1987,Americas,Saint Kitts and Nevis,Beer,1.98
1987,Americas,Guatemala,Other,0
1987,Africa,Mauritius,Wine,0.13
1985,Africa,Angola,Spirits,0.39
1986,Americas,Antigua and Barbuda,Spirits,1.55
1984,Africa,Nigeria,Other,6.1
1987,Africa,Botswana,Wine,0.2
1989,Americas,Guatemala,Beer,0.62

参数delimiter表示分割符号;dtype=str表示从文件中提取的数据以str格式存放;

ndarray是numpy中的数据结构;

2.ndarray

vector = numpy.array([5,10,15,20])
matrix = numpy.array([[5,10,15],[20,25,30],[35,40,45]])
print(vector)
print(matrix)

#
[ 5 10 15 20]
[[ 5 10 15]
 [20 25 30]
 [35 40 45]]

 看一下维度

vector1 = numpy.array([[1,2,3,4]])
vector2 = numpy.array([1,2,3,4])
print(vector1.shape)
print(vector2.shape)
matrix = numpy.array([[5,10,15],[20,25,30]])
print(matrix.shape)

#
(1, 4)
(4,)
(2, 3)

vector1可以看作是1×4的矩阵;vector2是一维数组,可以看作是列向量

再看ndarray的运算

a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = np.array([1,2,3])
c = np.array([[1,2,3]])
print(np.dot(a,b))
print('------------------')
print(np.dot(b,a))
print('------------------')
print(np.dot(c,a))
print('------------------')
print(np.dot(b,b))
print('------------------')
print(a*a)

#
[14 32 50]
------------------
[30 36 42]
------------------
[[30 36 42]]
------------------
14
------------------
[[ 1  4  9]
 [16 25 36]
 [49 64 81]]

a是3×3的矩阵,b是一个长度为3的一维数组,c是1×3的矩阵

np.dot(a,b)可以看作是3×3的矩阵和3×1的矩阵相乘

np.dot(b,a)看作是1×3的矩阵和3×3的矩阵相乘

np.dot(c,a)看作是矩阵和矩阵相乘

注意,np.dot(b,b)是向量内积,是把各个维度都加起来

a*a是矩阵对应位置上各个元素的乘积

 ——————分割线——————————————

numbers = numpy.array([1,2,3,'4'])
print(numbers)
numbers.dtype

#

['1' '2' '3' '4']

只要array中有一个元素不是int32或者int64,那么所有的元素数据类型就会变成其他的数据类型

对txt文件进行操作

 1 Year,WHO region,Country,Beverage Types,Display Value
 2 1986,Western Pacific,Viet Nam,Wine,0
 3 1986,Americas,Uruguay,Other,0.5
 4 1985,Africa,Cte d'Ivoire,Wine,1.62
 5 1986,Americas,Colombia,Beer,4.27
 6 1987,Americas,Saint Kitts and Nevis,Beer,1.98
 7 1987,Americas,Guatemala,Other,0
 8 1987,Africa,Mauritius,Wine,0.13
 9 1985,Africa,Angola,Spirits,0.39
10 1986,Americas,Antigua and Barbuda,Spirits,1.55
11 1984,Africa,Nigeria,Other,6.1
12 1987,Africa,Botswana,Wine,0.2
13 1989,Americas,Guatemala,Beer,0.62

①去掉表头,取出第二行,第五列的值以及第三行,第三列的值

world_alcohol = np.genfromtxt("world_alcohol.txt",delimiter=",",dtype=str,skip_header=1)
uruguay_other_1986 = world_alcohol[1,4]
third_country = world_alcohol[2,2]
print(uruguay_other_1986)
print(third_country)

#
0.5
Cte d'Ivoire

 补充一下切片操作:

vector = numpy.array([5,10,15,20])
print(vector[0:3])

#
[ 5 10 15]

取出第0-2个元素

 ——————分割线——————————————

matrix = numpy.array([
                    [5,10,15],
                    [20,25,30],
                    [35,40,45]
                     ])
print(matrix[:,1])

#
[10 25 40]

取出第二列所有元素 

 ——————分割线——————————————

matrix = numpy.array([
                    [5,10,15],
                    [20,25,30],
                    [35,40,45]
                     ])
print(matrix[:,0:2])

#
[[ 5 10]
 [20 25]
 [35 40]]

取出前两列元素

判断

vector = np.array([5.10,15,20])
vector == 10

#
array([False, False, False])

判断当前数据结构中有没有该元素

也可以借bool值来进行索引

vector = np.array([5,10,15,20])
equal_to_ten = (vector == 10)
print(equal_to_ten)
print(vector[equal_to_ten])

#
[False  True False False]
[10]

 当然,在矩阵中就是如下:

matrix = np.array([
                    [5,10,15],
                    [20,25,30],
                    [35,40,45]
                     ])
second_column_25 = (matrix[:,1]==25)
print(second_column_25)
print(matrix[second_column_25, :])

#
[False  True False]
[[20 25 30]]

对第二列的元素进行判断;然后取出元素等于25的那一列所在行

——————————-分割线——————————————

接下去是数值类型转换

vector = numpy.array(["1","2","3"])
print(vector.dtype)
print(vector)
vector = vector.astype(float)
print(vector.dtype)
print(vector)

#
<U1
['1' '2' '3']
float64
[1. 2. 3.]

从str类型转到float类型

关于sum求和操作

matrix = np.array([
                    [5,10,15],
                    [20,25,30],
                    [35,40,45]
                     ])
print(matrix.sum(axis=1))
print(matrix.sum(axis=0))
[ 30  75 120]
[60 75 90]

axis=1表示按行求和;axis=0表示按列求和

 Numpy常用函数

①矩阵的属性

print(np.arange(15))
a = np.arange(15).reshape(3,5)
print(a)
print(a.shape)
print(a.ndim)
print(a.dtype.name)
print(a.size)

#

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

np.arange,依次生成0-14的一维数组;

reshape(3,5),转换为3×5的矩阵;

ndim看看维度是多少

dtype.name,看看元素数据类型

size看看一共有多少元素 

②矩阵的初始化

a = np.zeros((3,4))
a

#
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
 

表示生成3行,四列的全0矩阵,其中(3,4)可以是[3,4]格式;

默认dtype=np.float64

——————————————————分割线——————————

np.ones((2,3,4), dtype=np.int32)

#
array([[[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]],

       [[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]]])

表示生成2个3×4的全1矩阵

——————————————————分割线——————————

np.arange(10,30,5)
np.arange(0, 2, 0.3)
np.arange(12).reshape(4,3)

#
[10 15 20 25]
[0.  0.3 0.6 0.9 1.2 1.5 1.8]
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]

从10开始,每隔5取一个数,左闭右开

——————————————————分割线——————————

np.random.random((2,3))

#
array([[0.04286104, 0.02303494, 0.35769307],
       [0.34801234, 0.63580499, 0.99897693]])

表示随机生成2×3的矩阵

——————————————————分割线——————————

from numpy import pi
np.linspace(0, 2*pi, 100)

#
array([0.        , 0.06346652, 0.12693304, 0.19039955, 0.25386607,
       0.31733259, 0.38079911, 0.44426563, 0.50773215, 0.57119866,
       0.63466518, 0.6981317 , 0.76159822, 0.82506474, 0.88853126,
       0.95199777, 1.01546429, 1.07893081, 1.14239733, 1.20586385,
       1.26933037, 1.33279688, 1.3962634 , 1.45972992, 1.52319644,
       1.58666296, 1.65012947, 1.71359599, 1.77706251, 1.84052903,
       1.90399555, 1.96746207, 2.03092858, 2.0943951 , 2.15786162,
       2.22132814, 2.28479466, 2.34826118, 2.41172769, 2.47519421,
       2.53866073, 2.60212725, 2.66559377, 2.72906028, 2.7925268 ,
       2.85599332, 2.91945984, 2.98292636, 3.04639288, 3.10985939,
       3.17332591, 3.23679243, 3.30025895, 3.36372547, 3.42719199,
       3.4906585 , 3.55412502, 3.61759154, 3.68105806, 3.74452458,
       3.8079911 , 3.87145761, 3.93492413, 3.99839065, 4.06185717,
       4.12532369, 4.1887902 , 4.25225672, 4.31572324, 4.37918976,
       4.44265628, 4.5061228 , 4.56958931, 4.63305583, 4.69652235,
       4.75998887, 4.82345539, 4.88692191, 4.95038842, 5.01385494,
       5.07732146, 5.14078798, 5.2042545 , 5.26772102, 5.33118753,
       5.39465405, 5.45812057, 5.52158709, 5.58505361, 5.64852012,
       5.71198664, 5.77545316, 5.83891968, 5.9023862 , 5.96585272,
       6.02931923, 6.09278575, 6.15625227, 6.21971879, 6.28318531])

表示从0开始,到2π,按均匀分布取100个值

——————————————分割线—————————

a = np.array([20,30,40,50])
b = np.arange(4)
print(a)
print(b)
c = a-b
print(c)
c = c-1
print(c)
print(b**2)
print(a<35)

#
[20 30 40 50]
[0 1 2 3]
[20 29 38 47]
[19 28 37 46]
[0 1 4 9]
[ True  True False False]

a-b就是每个对应位置元素相减

———————————————分割线———————

A = np.array([[1,1],
             [0,1]])
B = np.array([[2,0],
             [3,4]])
print(A)
print('------------')
print(B)
print('------------')
print(A*B)
print('------------')
print(A.dot(B))
print('------------')
print(np.dot(A, B))

#
[[1 1]
 [0 1]]
------------
[[2 0]
 [3 4]]
------------
[[2 0]
 [0 4]]
------------
[[5 4]
 [3 4]]
------------
[[5 4]
 [3 4]]

前文也详细写了numpy不同乘法的区别

③矩阵常用操作

B = np.arange(3)
print(B)
print(np.exp(B))
print(np.sqrt(B))

#
[0 1 2]
[1.         2.71828183 7.3890561 ]
[0.         1.         1.41421356]

exp表示e的x次幂;sqrt表示开平方

———————————————分割线———————

a = np.floor(10*np.random.random((3,4)))
print(a)
print('--------------')
print(a.ravel())
print('--------------')
a.shape = (6,2)
print(a)
print('--------------')
print(a.T)

#
[[8. 3. 6. 2.]
 [0. 8. 7. 3.]
 [5. 2. 0. 7.]]
--------------
[8. 3. 6. 2. 0. 8. 7. 3. 5. 2. 0. 7.]
--------------
[[8. 3.]
 [6. 2.]
 [0. 8.]
 [7. 3.]
 [5. 2.]
 [0. 7.]]
--------------
[[8. 6. 0. 7. 5. 0.]
 [3. 2. 8. 3. 2. 7.]]

floor表示向下取整,也就是往小的数取整;

a.ravel()表示把矩阵拉成一个向量;

a.shape=(6,2) 相当于a = a.reshape(6,2)

也可以是a.shape=(6,-1)或者a = a.reshape(6,-1)意思是指定一个维度,另一个维度自己去算

a.T也就是求转置

—————————————分割线————————

a = np.floor(10*np.random.random((2,2)))
b = np.floor(10*np.random.random((2,2)))
print(a)
print('-----')
print(b)
print('-----')
print(np.hstack((a,b)))
print('-----')
print(np.vstack((a,b)))

#
[[6. 7.]
 [1. 1.]]
-----
[[0. 3.]
 [9. 9.]]
-----
[[6. 7. 0. 3.]
 [1. 1. 9. 9.]]
-----
[[6. 7.]
 [1. 1.]
 [0. 3.]
 [9. 9.]]

hstack表示按行拼接;vstack表示按列拼接

————————————————分割线——————

a = np.floor(10*np.random.random((2,12)))
print(a)
print('------')
print(np.hsplit(a,3))
print('------')
print(np.hsplit(a,(3,4)))
a = np.floor(10*np.random.random((12,2)))
print('------')
print(a)
np.vsplit(a,3)

#
[[4. 6. 5. 6. 0. 9. 7. 9. 3. 3. 0. 6.]
 [5. 5. 6. 1. 6. 2. 5. 3. 3. 9. 8. 1.]]
------
[array([[4., 6., 5., 6.],
       [5., 5., 6., 1.]]), array([[0., 9., 7., 9.],
       [6., 2., 5., 3.]]), array([[3., 3., 0., 6.],
       [3., 9., 8., 1.]])]
------
[array([[4., 6., 5.],
       [5., 5., 6.]]), array([[6.],
       [1.]]), array([[0., 9., 7., 9., 3., 3., 0., 6.],
       [6., 2., 5., 3., 3., 9., 8., 1.]])]
------
[[2. 0.]
 [0. 2.]
 [1. 4.]
 [3. 7.]
 [0. 0.]
 [7. 5.]
 [0. 7.]
 [3. 5.]
 [7. 9.]
 [1. 4.]
 [2. 4.]
 [8. 1.]]
[array([[2., 0.],
       [0., 2.],
       [1., 4.],
       [3., 7.]]), array([[0., 0.],
       [7., 5.],
       [0., 7.],
       [3., 5.]]), array([[7., 9.],
       [1., 4.],
       [2., 4.],
       [8., 1.]])]
hsplit(a,3)表示按行切分,均分成3部分;

hsplit(a,(3,4))表示在第2个位置切分,以及第3个位置切分
同理,vsplit表示按列切分
③复制常用操作
a = np.arange(12)
b = a
print(b is a)
b.shape = 3,4
print(a.shape)
print(id(a))
print(id(b))

#
True
(3, 4)
2570788546080
2570788546080
赋值操作,a和b完全指向一个元素,把b的维度修改一下,a也改变了
————————————————分割线——————————————————
c = a.view()
print(c is a)
c.shape =2,6
print(a.shape)
c[0,4] = 1234
print(a)
print(id(a))
print(id(c))

#
False
(3, 4)
[[   0    1    2    3]
 [1234    5    6    7]
 [   8    9   10   11]]
2570788546080
2570788626560

可以看出这是一个浅复制,a和c指向不同的元素,但共用值,改变c的元素,其实也改变了a的元素

————————————————分割线——————————————————
 那么既想让复制的值指向不同的元素,也不想让他们共用值,可以进行深复制
d = a.copy()
d is a
d[0,0]= 9999
print(d)
print(a)

#

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

改变d的元素,对a毫无影响,同时改变a或者d的维度,对对方也毫无影响

————————————————分割线————————————————
补充一点关于索引的内容
data = np.sin(np.arange(20)).reshape(5,4)
print(data)
ind = data.argmax(axis=0)
print(ind)
data_max = data[ind, range(data.shape[1])]
print(data_max)

#
[[ 0.          0.84147098  0.90929743  0.14112001]
 [-0.7568025  -0.95892427 -0.2794155   0.6569866 ]
 [ 0.98935825  0.41211849 -0.54402111 -0.99999021]
 [-0.53657292  0.42016704  0.99060736  0.65028784]
 [-0.28790332 -0.96139749 -0.75098725  0.14987721]]
[2 0 3 1]
[0.98935825 0.84147098 0.99060736 0.6569866 ]
axis表示按列索引;
ind相当于是把每列中最大数的行给拿出来放到一个ndarray中;
注意data[,]取数的方法,很巧妙,ind是按行作索引,range(data.shape[1])相当于把一共多少列给变成了range循环(python基础)

————————————分割线—————————

接下去是扩展操作

a = np.arange(0,40,10)
print(a)
b= np.tile(a,(3,5))
print(b)

#
[ 0 10 20 30]
[[ 0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30]
 [ 0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30]
 [ 0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30  0 10 20 30]]

相当于把一个维度的向量扩展成所需类型的矩阵,矩阵每个元素都是相同的向量

————————————分割————————————

a = np.array([[4,3,5],[1,2,1]])
print(a)
print('-------')
b = np.sort(a,axis=1)
print(b)
a.sort(axis=1)
print('-------')
print(a)
a = np.array([4,3,1,2])
j= np.argsort(a)
print('-------')
print(j)
print('-------')
print(a[j])

#
[[4 3 5]
 [1 2 1]]
-------
[[3 4 5]
 [1 1 2]]
-------
[[3 4 5]
 [1 1 2]]
-------
[2 3 1 0]
-------
[1 2 3 4]

axis=1表示按行索引排序

argsort表示按元素值从小到大,对其索引进行排序

a[j]又表示按照索引对其元素值进行排序,其实就是从小到大排序

————————————————分割线————————————
x_data = np.linspace(-1,1,300)[:, np.newaxis]
比如,今天写了这么一行代码,意思是生成-1到1的300个均匀分布值(300,),然后变成(300,1)
noise = np.random.normal(0,0.05,x_data.shape)

表示生成一个正态分布,均值为0,标准差为0.05,维度为x_data的维度,

所以标准正态分布则是

np.random.normal(loc=0,scale=1,size=None)

也相当于

np.random.randn(size=None)

————————————————分割线————————————

又发现一个很绝的操作,那就是shuffle,先看代码

p = np.random.permutation(3)
a = np.array([1,0,2])
print(a,p)
print(type(a))
print(type(p))
print(np.array([1,2,3])[a])
print(np.array([1,2,3])[p])

#
[1 0 2] [2 0 1]
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
[2 1 3]
[3 1 2]
np.random.permutation(3)这个其实效果np.array是类似的,都是生成ndarray的一维数组,不同的是前一个函数是“字典”shuffle的,把数组已经打乱了,其实真正神奇的,原来
ndarray格式的数据后面加[ndarray]这个索引,就可以对数组里面的元素起到按索引排序的效果,简直牛逼。。以前一直不知道!


人生苦短,何不用python
原文地址:https://www.cnblogs.com/yqpy/p/11004190.html