数据分析与机器学习一:矩阵计算numpy

导入numpy库:

import numpy as np

 

一、生成numpy.ndarray矩阵

1、使用numpy.genfromtext()从.txt文件读入数据 --> 生成numpy.ndarray矩阵

# 从txt文件读取数据,dtype读进来的数据类型,delimiter分隔符
world_alcohol = np.genfromtxt("world_alcohol.txt", delimiter=",", dtype=str)
#读进来的数据是什么类型:numpy.ndarray,numpy类型的矩阵
print (type(world_alcohol))
print (world_alcohol)
[['Year' 'WHO region' 'Country' 'Beverage Types' 'Display Value']
 ['1986' 'Western Pacific' 'Viet Nam' ' Wine' '0.69']
 ['1985' 'Africa' "Cte d'Ivorie" 'Wine' '1.62']]

 print (help(np.genfromtxt))

2.使用numpy.array(),对现有列表,生成numpy.ndarray矩阵

# 生成一维矩阵
vector = np.array([5, 10, 15, 20])
print (vector)
[ 5 10 15 20]
# 生成二维矩阵
matrix = np.array([[5, 10, 15], [20, 25, 30]])
print (matrix)
[[ 5 10 15]
 [20 25 30]]

 

3.初始化一个矩阵:

  • np.arange(range总数):初始化一个值range的一维矩阵,参数为range总数
  • np.arange(起始数,终止数,步长):同上,参数为:起始数,终止数,步长
  • np.zeros((行数, 列数.....第n维)):初始化一个值都为0的矩阵,参数为元组
  • np.ones((行数,列数.....第n维)):初始化一个值都为1的矩阵,参数为元组
  • np.random.random((行数,列数.....第n维)):初始化一个随机数的矩阵,参数为元组
  • np.linspace(起始数,终止数,总数):初始化一个矩阵,参数为:起始数,终止数,总数
import numpy as np
a = np.arange(15)  # 初始化一个随机值的一维矩阵,共15个数
a
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
np.arange(2, 10, 2)  # 生成一个随机数的一维矩阵:起始值为2,终止值为10,步长为2
# array([2, 4, 6, 8])
np.zeros((3, 5))   # 初始一个值都为0的3行5列的矩阵
# array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])
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]]])
np.linspace(0, 98, 50, dtype=np.int32)
# array([ 0,  2,  4,  6, .......98])

 

 

二、对numpy.ndarray矩阵取值

1.使用ndarray.shape:查看ndarray矩阵的结构

print (world_alcohol.shape)
# (3, 5)  三行五列,二维矩阵
print (vector.shape)
#(4,) 一维矩阵,4个元素
print (matrix.shape)
# (2, 3) 二行三列,二维矩阵

 

2.使用ndarray.dtype:查看矩阵的数据类型

注意:ndarray里的数据,都是相同类型的数据

print (world_alcohol.dtype)
print (vector.dtype)
print (matrix.dtype)
print (np.array([1.2, 3, 4]).dtype)
<U15
int32
int32
float64
print (np.array([1.2, 3, 4]))
# [1.2 3.  4. ]

 

注意:改变ndarray任何一个数据的数据类型,将改变所有数据的类型

使用ndarray.astype(新的数据类型):转换ndarray的数据类型:

vector=vector.astype(float)
print (vector.dtype)
# float64
print (vector)
#  [ 5. 10. 15. 20.]

 

 

3.使用索引,读取ndarray矩阵的数据

# 取二维矩阵的数据
x = world_alcohol[1, 3]  #第2行,第4列的数据
print (x)
print(world_alcohol[1,1])  # 第2行,第2列的数据
#  Wine
# Western Pacific
matrix[1,2] #第2行第3列的数据
# 30
# 取一维矩阵的数据
vector[1,]   # 取一维矩阵的第2个元素
# 10
#取二维矩阵的第2行
matrix[1,]
# [20, 25, 30]

 

4.使用切片,读取ndarray矩阵的数据

# 对一维矩阵切片
print (vector[0:3])
print (vector[:3])
# [ 5 10 15]
# [ 5 10 15]

 

# 对二维矩阵切片
print (matrix[:, 1]) # 取所有行,第1列 
print (matrix[0:2, 1])  # 取0-2行,第1列
print (matrix[0:2, 0:2])  # 取0-2行,0-2列
print (matrix[:, :]) # 取所有行,所有列

[10 25]
[10 25]
[[ 5 10]
 [20 25]]
[[ 5 10 15]
 [20 25 30]]

 

5.比较矩阵中的数据:ndarray = 某值

print (vector)
vector == 10   #判断矩阵的数据每一个数据是否与10相等,是的数据返回True,不是的数据返回False,的array列表
# [ 5 10 15 20]
# Out[35]: array([False,  True, False, False])

 

 

注意:与ndarray比较,会对ndarray中的每个元素,都进行比较

如果只对矩阵中,某些值进行比较,可以先切片,再比较:

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

 

 

6.使用bool值当索引,取ndarray中的数据

print (vector)
equal_to_ten = (vector == 10)
print (equal_to_ten)
print (vector[equal_to_ten])  #使用bool值,取ndarray中的数据,返回True的元素

[ 5 10 15 20]
[False  True False False]
[10]
print (matrix)
print (matrix[:, 2])
second_column_15 = (matrix[:, 2] == 15) #比较第2列中的数据,等于15的元素返回True,否则返回False
print (second_column_15)
print (matrix[second_column_15, :])  # 取所有列,取行为second_column_15的布尔值的索引(第1行)

[[ 5 10 15]
 [20 25 30]]
[15 30]
[ True False]
[[ 5 10 15]]  #第1行的所有列

7.使用索引,重新赋值矩阵中的元素 或行列

print (matrix)
matrix[second_column_25, 1] = 10
print (matrix)
#[[ 5 10 15]
# [20 25 30]
# [35 40 45]]
#[[ 5 10 15]
# [20 10 30]
# [35 40 45]]

 

三、ndarray中的操作方法1:

1.求和:ndarray.sum(axis=行1|列0);如果不指定参数,则对所有行列求和

示例:对列进行求和;当axis=0的时侯,是对列进行求值;当axis=1时,是对行进行求值

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

 

2.求均值:ndarray.mean(axis),如果不指定参数,则对所有行列求均值

matrix.mean()
#25.0
matrix.mean(axis=0)
# array([20., 25., 30.])

 

3.找出None值:numpy.isnan(矩阵),注意isnan方法是numpy的方法

示例:对所有行,判断第5个值是否为None;所有行第5列,转换后为一维矩阵,因此判断isnan的结果也是一维矩阵。如果给的矩阵是二维矩阵,那么判断isnan的结果也是二维矩阵

world_alcohol = numpy.genfromtxt("world_alcohol.txt", delimiter=",")
is_value_empty = numpy.isnan(world_alcohol[:,4])
print (is_value_empty)
# [ True False False False False False False False False False False False
 False False False False False False False False False False False False...........]

 并将None值替换为0

world_alcohol[is_value_empty, 4] = '0'

转换矩阵结构,生成新的矩阵:ndarray.reshape(行数,列数)

a = np.arange(15)

b=a.reshape(3,5) # 将一维矩阵a,转换成3行5列的二维矩阵
b
# array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

 

注意:

  • reshare是非原地修改;原矩阵不变,修改的结果是返回新矩阵
  • 如果行*列的总数,与原数组的总数不相等,则转换失败,抛出异常
a.dtype.name
# 'int32'

 

进行其它数学函数运算,如sin:np.sin(矩阵)

np.sin(b)
array([[ 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]])

 

三、ndarray中的操作方法2:矩阵的外部操作

加减、大小比较运算:

a=np.array([20, 30, 40, 50])
b=np.arange(4)
c=a-b
c
# array([20, 29, 38, 47])
c=c-1
c
# array([18, 27, 36, 45])
d=c**2
d
# array([ 324,  729, 1296, 2025], dtype=int32)

 

d<800
# array([ True,  True, False, False])

 

乘法运算:

a=np.array([[1, 1], [0, 1]])
b=np.array([[2, 0], [3, 4]])
a*b  # 对应位置相乘
# array([[2, 0],
       [0, 4]])
a.dot(b)  #矩阵的乘法:a矩阵的一行的所有元素分别乘以b矩阵所有行的相应的列,再相加
# 如:a矩阵的第1行第1列*b矩阵的第1行第1列,加上a矩阵的第1行第2列*b矩阵的第2行第1 列....a矩阵的第1行第n列*b矩阵的第n行第1列
# 依次,a矩阵的第1行第1列*b矩阵的第1行第2列,加上a矩阵的第1行第2列*b矩阵的第2行第2 列....a矩阵的第1行第n列*b矩阵的第n行第2列
# ...a矩阵的第一行一直乘到b矩阵的第n列
# 依次,a矩阵的第2行,再做以上循环
# 1*2+1*3, 1*0+1*4, 0*2+1*3, 0*0+1*4


#array([[5, 4],
       [3, 4]])
np.dot(a, b)  #等同以上

 

平方根:

import numpy as np
B = np.arange(3)
print (B)
print (np.sqrt(B))
[0 1 2]
[0.         1.         1.41421356]

e次方:
print (np.exp(B))
# [1.         2.71828183 7.3890561 ]

 

矩阵结构转换:

#Return the floor of the input
a = np.floor(10*np.random.random((3,4)))  #未指定小数点后的位数,则默认为0,即取整
print (a)
print(a.shape)
## flatten the array
print (a.ravel()) # 把矩阵转换为向量,即转换为一维矩阵,返回新的矩阵
a.shape = (6, 2)  #相当于a=a.reshare(6, 2),改变ndarray结构为6行2列
print (a)
print (a.T) # 改变ndarray矩阵的结构,改变为相反的结构,即2行6行,返回新的矩阵;即,转置矩阵
a.shape = (3, -1)  # 指定行,自动计算列;-1表示自动计算
print (a)
[[5. 5. 3. 5.]
 [1. 0. 4. 1.]
 [4. 3. 8. 7.]]
(3, 4)
[5. 5. 3. 5. 1. 0. 4. 1. 4. 3. 8. 7.]
[[5. 5.]
 [3. 5.]
 [1. 0.]
 [4. 1.]
 [4. 3.]
 [8. 7.]]
[[5. 3. 1. 4. 4. 8.]
 [5. 5. 0. 1. 3. 7.]]
[[5. 5. 3. 5.]
 [1. 0. 4. 1.]
 [4. 3. 8. 7.]]

 

矩阵拼接:

np.hstack((矩阵1, 矩阵2)):按行拼接

np.vstack((矩阵1, 矩阵2)):按列拼接

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)))
[[7. 2.]
 [5. 5.]]
------
[[9. 0.]
 [3. 0.]]
-------
[[7. 2. 9. 0.]
 [5. 5. 3. 0.]]

 

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.vstack((a,b)))
[[3. 1.]
 [4. 6.]]
------
[[8. 4.]
 [4. 7.]]
-------
[[3. 1.]
 [4. 6.]
 [8. 4.]
 [4. 7.]]

 

矩阵的切分:np.vsplit(a, 3)

  • np.hsplit(矩阵,切分成n份):按行切分,切成n份,即n个array
  • np.hsplit(矩阵,(列的索引1,列的索引2.....)):按行切分,切分位置为列的索引1,2......
  • np.vpslit():同以上,刚好相反;按列切分
a = np.floor(10*np.random.random((2,6)))
print (a)
print (np.hsplit(a, 3))  # 按行,切成3份
print (np.hsplit(a,(3,4)))   # 按行切分,在列的索引3和4前面分别切一刀
print ('------')
a.shape = (6, 2)
print (a)
print (np.vsplit(a, 3))  #按列,切成3份
print (np.vsplit(a, (3, 4)))  # 按列切分,在行的索引3和4前面分别切一刀
[[0. 1. 1. 2. 5. 9.]
 [6. 1. 5. 9. 9. 3.]]
[array([[0., 1.],
       [6., 1.]]), array([[1., 2.],
       [5., 9.]]), array([[5., 9.],
       [9., 3.]])]
[array([[0., 1., 1.],
       [6., 1., 5.]]), array([[2.],
       [9.]]), array([[5., 9.],
       [9., 3.]])]
------
[[0. 1.]
 [1. 2.]
 [5. 9.]
 [6. 1.]
 [5. 9.]
 [9. 3.]]
[array([[0., 1.],
       [1., 2.]]), array([[5., 9.],
       [6., 1.]]), array([[5., 9.],
       [9., 3.]])]
[array([[0., 1.],
       [1., 2.],
       [5., 9.]]), array([[6., 1.]]), array([[5., 9.],
       [9., 3.]])]

 将矩阵转为向量,除了ndarray.ravel(),还可以使用ndarray.flag

x=np.array([[1,2,3],[9,8,7],[6,5,4]])
x.ravel()
# array([1, 2, 3, 9, 8, 7, 6, 5, 4])
x.flat[:]
array([1, 2, 3, 9, 8, 7, 6, 5, 4])
x.flat[2:6]  #转为向量,并只取部分数据
# array([3, 9, 8, 7])

 

ndarray.max(axis=None, out=None):返回指定轴的最大值

ndarray.argmax(axis=None, out=None):返回指定轴的最大元素索引值

import numpy as np
data = np.floor(100*np.random.random((3, 3)))
print (data)
print (data.max())  # 返回矩阵的最大值
print (data.argmax())  # 返回矩阵的最大值的索引
print (data.argmax(axis=0)) # 返回每列的最大值的索引

print (data.argmax(axis=1)) # 返回每行的最大值的索引
[[12. 73. 58.]
 [31. 14.  8.]
 [99. 46. 47.]]
99.0
6
[2 0 0]
[1 0 0]

 

根据索引值,找出对象的值

ndarray.min(axis=None, out=None):返回指定轴的最小值

ndarray.argmin(axis=None, out=None):返回指定轴最小元素的索引。

五、ndarray的复制:

ndarray同list一样,赋值时如果引用了其它列表,它们是同一个对象;

a = np.arange(6)
b=a
print (b is a)   # True,b并没有创建新的对象,只是对a对象的引用,a和b指向同一个数据对象
b.shape=2,-1
print (b is a)   # True
b[0,0]=999
print(a)
print(b)
True
True
[[999   1   2]
 [  3   4   5]]
[[999   1   2]
 [  3   4   5]] 

矩阵中的浅复制,改变了引用对象,复制前后的对象并不是同一个对象;尽管它们不是同一个对象,但是它们有浅复制的部分特性,共享数据,包括视图view()方法,切片方法,shape改变等,仍共享数据。(或者说外层对象不一样,但内层对象一样)

浅复制:ndarray.view(),也称为视图对象。view()创建了一个新的对象,但是这两个对象共享相同的数据

a = np.arange(6)
b = a.view()
print(a)
print (b is a)   # False
b.shape=2,-1
print (b is a)   # False
b[0,0]=999  # 不是同一对象,但共享数据,因此a将跟随b变化
print(a)
print(b)
print('---------')
b = [11,22,33]  # 这是重新创建了一个对象,且对象与a没关系,当然此时a和b是不共享数据的。
print(a)
print(b)
[0 1 2 3 4 5]
False
False
[999   1   2   3   4   5]
[[999   1   2]
 [  3   4   5]]
---------
[999   1   2   3   4   5]
[11, 22, 33]
a=np.array([[1,2,3],[4,5,6]])
b=a.view()
b[0,0]=111
print (a)
print (b)
#结果一样,共享数据:[[111   2   3], [  4   5   6]]
b[0]=[10,20,30]  
print (a)
print (b)
#结果一样,共享数据:[[10 20 30], [ 4  5  6]]

 

深复制,内外层都是独立的对象。

深复制:ndarray.copy(),不仅不是同一个对象,且不共享数据。(或者说内外层对象都不一样)

np.tile(矩阵,(行复制的份数,以行复制的结果再进行列复制的份数))

a=np.arange(0, 40, 10)
b=np.tile(a, (4, 3))
#array([[ 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]])

 

np.sort(矩阵,axis=1|0):按行或列进行排序,默认按升序排序,返回新的矩阵

a=np.array([[4,1,3],[3,5,1], [3,3,4]])
np.sort(a, axis=1)
# array([[1, 3, 4],
       [1, 3, 5],
       [3, 3, 4]])

 

np.argsort(矩阵, axis=1|0):排序后,返回排序的索引值

np.argsort(a,axis=1)
# array([[1, 2, 0],
       [2, 0, 1],
       [0, 1, 2]], dtype=int64)

 

六、ndarray的其它方法:

参考:https://www.cnblogs.com/bonelee/p/7253966.html#undefined

ndarray.ptp(axis=None, out=None) : 返回数组的最大值—最小值或者某轴的最大值—最小值

ndarray.clip(a_min, a_max, out=None) : 小于最小值的元素赋值为最小值,大于最大值的元素变为最大值。

ndarray.all():如果所有元素都为真,那么返回真;否则返回假

ndarray.any():只要有一个元素为真则返回真

ndarray.swapaxes(axis1, axis2) : 交换两个轴的元素

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

 

 

改变数组维度和大小的方法:

ndarray.reshape(shape[, order]) :返回重命名数组大小后的数组,不改变元素个数.

ndarray.resize(new_shape[, refcheck]) :改变数组的大小(可以改变数组中元素个数).

ndarray.transpose(*axes) :返回矩阵的转置矩阵

ndarray.swapaxes(axis1, axis2) : 交换两个轴的元素后的矩阵.

ndarray.flatten([order]) : 复制一个一维的array出来.

ndarray.ravel([order]) :返回为展平后的一维数组.

ndarray.squeeze([axis]) :移除长度为1的轴。

ndarray.tolist():将数组转化为列表

ndarray.take(indices, axis=None, out=None, mode=’raise’):获得数组的指定索引的数据

a=np.arange(12).reshape(3,4)
print(a)
print (a.take([1,3],axis=1)) #提取1,3列的数据
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
array([[ 1,  3],
       [ 5,  7],
       [ 9, 11]])

numpy.put(a, ind, v, mode=’raise’):用v的值替换数组a中的ind(索引)的值。Mode可以为raise/wrap/clip。Clip:如果给定的ind超过了数组的大小,那么替换最后一个元素。

numpy.repeat(a, repeats, axis=None):重复数组的元素

x = np.array([[1,2],[3,4], [5, 6]])
np.repeat(x, 2)  #如果没有指定axis,则转为一维矩阵
np.repeat(x, 2, axis=1)  # 如果axis=1,行数保持不变,在列内复制元素
np.repeat(x, 3, axis=0)  # 如果axis=0,列数保持不变,在行间复制元素

 

结果分别为:

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

numpy.tile(A, reps):根据给定的reps重复数组A,和repeat不同,repeat是重复元素,该方法是重复数组。

ndarray.var(axis=None, dtype=None, out=None, ddof=0):返回数组的方差,沿指定的轴。

ndarray.std(axis=None, dtype=None, out=None, ddof=0):沿给定的轴返回数则的标准差

ndarray.prod(axis=None, dtype=None, out=None):返回指定轴的所有元素乘机

ndarray.cumprod(axis=None, dtype=None, out=None):返回指定轴的累积,如下:

>>> a
array([[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]])
>>> a.cumprod(axis=1)  #得到竖轴的累积
array([[   0,    0,    0,    0],
[   4,   20,  120,  840],
[   8,   72,  720, 7920]])

ndarray.mean(axis=None, dtype=None, out=None):返回指定轴的数组元素均值

ndarray.cumsum(axis=None, dtype=None, out=None):返回指定轴的元素累计和。如:

>>> a
array([[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]])
>>> a.cumsum(axis=1)
array([[ 0,  1,  3,  6],
[ 4,  9, 15, 22],
[ 8, 17, 27, 38]])

ndarray.sum(axis=None, dtype=None, out=None):返回指定轴所有元素的和

ndarray.trace(offset=0, axis1=0, axis2=1, dtype=None, out=None):返回沿对角线的数组元素之和

ndarray.round(decimals=0, out=None):将数组中的元素按指定的精度进行四舍五入,如下:

>>> np.around([0.37, 1.64])
array([ 0., 2.])
>>> np.around([0.37, 1.64], decimals=1)
array([ 0.4, 1.6])
>>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value
array([ 0., 2., 2., 4., 4.])
>>> np.around([1,2,3,11], decimals=1) # ndarray of ints is returned
array([ 1, 2, 3, 11])
>>> np.around([1,2,3,11], decimals=-1)
array([ 0, 0, 0, 10])

ndarray.conj():返回所有复数元素的共轭复数,如:

>>> b=np.array([[1+2j,3+0j],[3+4j,7+5j]])
>>> b
array([[ 1.+2.j,  3.+0.j],
[ 3.+4.j,  7.+5.j]])
>>> b.conj()
array([[ 1.-2.j,  3.-0.j],
[ 3.-4.j,  7.-5.j]])

ndarray.argmin(axis=None, out=None):返回指定轴最小元素的索引。

ndarray.min(axis=None, out=None):返回指定轴的最小值

ndarray.argmax(axis=None, out=None):返回指定轴的最大元素索引值

ndarray.diagonal(offset=0, axis1=0, axis2=1):返回对角线的所有元素。

ndarray.compress(condition, axis=None, out=None):返回指定轴上条件下的切片。

ndarray.nonzero():返回非零元素的索引

 

posted on 2018-09-09 07:47  myworldworld  阅读(463)  评论(0)    收藏  举报

导航