数据分析与机器学习一:矩阵计算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) 收藏 举报