python数据分析与机器学习之numpy操作

python数据分析与机器学习之numpy操作

numpy简介

机器学习三剑客想必大家都知道,分别是numpy、pandas和matplotlib了,numpy是对ndarray格式的数组进行操作的一个Python的库,同时也是机器学习的基础,在学习一些常用的深度学习框架之前,对于numpy的学习也是必不可少的,同时,numpy也是pandas的基础(对于pandas的结构留在pandas部分再介绍),故在此贴出一些numpy的常用操作帮大家尽快入门机器学习。

代码示例

建议在Python3版本中运行,代码较多但是不难,其中有不少都是print()来使得同学们了解输出的样式来方便学习

第一部分是一个导入文件操作,本次使用的是world_alcohol.txt的数据集,大家可以随意生成一个以逗号作为分隔的txt文本作文数据集来感受基本操作。如果有同学需要的话,请留言我会发出来供大家学习交流使用。

import numpy as np

# numpy读入数据
# 第一个参数是读入数据的完整路径,这里使用的相对路径
# 第二个参数delimiter是数据的分隔符,元素和元素之间如何分割,如果是逗号就写逗号,空格就打个空格
# dtype定义了数据用什么方式去读,如果数据既有string也有float,先用str读进来,之后再类型转换
world_alcohol = np.genfromtxt("world_alcohol.txt",
                              delimiter=",",
                              dtype=str)

# 查看变量的结构
# numpy读进来的数据都是numpy.ndarray形式
print(type(world_alcohol))

# 查看数据内容
print(world_alcohol)
# 查看某个函数的帮助
print(help(np.genfromtxt))

ndarray是numpy的基本结构,之后大多的操作都是基于ndarray的操作

# numpy.array() function can take a list or list of lists as input, when input a list, we get a one-dimension vector
vector = np.array([5,10,15,20])
# when we input a list of list, we get a matrix as a result
matrix = np.array([[5,10,15],
                   [20,25,30],
                   [35,40,45]])
print(vector)
print(matrix)
print(vector.shape)
print(matrix.shape)

# each value in a Numpy array has to have the same data type
# 所有数据会一致为更通用的格式
# numbers1为int32
numbers1 = np.array([1, 2, 3, 4])
print(numbers1.dtype)
# numbers2为float64,因为4.是float
numbers2 = np.array([1, 2, 3, 4.])
print(numbers2.dtype)
# numbers3为string类型
numbers3 = np.array([1, 2, 3, '4'])
print(numbers3.dtype)

# numpy用索引去取数据
# 此时已经导入world_alcohol,直接用索引查找
# 下标索引都是从0开始
temp1 = world_alcohol[1, 2]
print(temp1)
# 左闭右开
vector = np.array([5, 10, 15, 20])
print(vector[0:3])
matrix = np.array([[5, 10, 15],
                   [10, 15, 20],
                   [30, 35, 40]])
print(matrix[:, 1])
print(matrix[:, 0:2])
print(matrix[0:2, 0:2])


# 用numpy进行运算
# 判断,使用  数组名 == 常量   的形式来判断,返回的是数组中每个值与常量比较的bool值
vector = np.array([5, 10, 15, 20])
print(vector == 10)
# 可将返回的值当做索引
equal_to_ten = (vector == 10)
print(equal_to_ten)
# vector[equal_to_ten]会把true对应的值返回,而false对应的值不返回
print(vector[equal_to_ten])


matrix = np.array([[5, 10, 15],
                   [10, 15, 20],
                   [20, 25, 30]])
print(matrix == 15)
# 检查第二列是否有值等于15
seccond_colunm_15 = (matrix[:, 1] == 15)
print(seccond_colunm_15)
# 返回第二列中的值是15的元素对应的那一行
print(matrix[seccond_colunm_15, :])

# 判断 与 或 的判断
vector = np.array([5,10,15,20])
# 判断 与
equal_to_ten_and_five = (vector == 10) & (vector == 5)
print(equal_to_ten_and_five)
# 判断 或
equal_to_ten_or_five = (vector == 10) | (vector == 5)
print(equal_to_ten_or_five)
# 将vector中等于5或10的元素赋值为50
vector[equal_to_ten_or_five] = 50
print(vector)

# 矩阵的 与 或 判断
matrix = np.array([[5, 10, 15],
                   [10, 15, 20],
                   [20, 25, 30]])
equal_to_ten_and_five = (matrix == 5) & (matrix == 10)
print(equal_to_ten_and_five)
equal_to_ten_or_five = (matrix == 5) |(matrix == 10)
print(equal_to_ten_or_five)
print(matrix[equal_to_ten_or_five])
matrix[equal_to_ten_or_five] = 100
print(matrix)


# 对值的类型进行改变
# we can convert the data type of an array with the ndarray.astype() method
vector = np.array(['1', '2', '3', '4'])
print(vector.dtype)
print(vector.shape)
print(vector)
vector = vector.astype(float)
print(vector.dtype)
print(vector)

# numpy求极值
# min() max() sum() sum(axis=1) sum(axis=0)
# print(help(numpy.array))来了解更多属性
vector = np.array([5, 10, 15, 20])
temp = vector.min()
print(temp)
print(vector.max())

# 求和,可按行求和、按列求和、求所有元素和
matrix = np.array([[5, 10, 15],
                   [20, 25, 30],
                   [35, 40, 45]])
# axis = 1 相当于对行求和
temp1 = matrix.sum(axis=1)
# axis = 0 相当于对列求和
temp2 = matrix.sum(axis=0)
print(temp1)
print(temp2)
print(matrix.sum(axis=1))
print(matrix.sum(axis=0))


# 矩阵变换
# np.arange() np.zeros() np.ones() np.random.random(),传参注意是元组还是数
# 生成一个具有15个元素的顺序向量,默认从0开始,等差为1
print(np.arange(15))
a = np.arange(15).reshape(3, 5)
print(a)
print(a.shape)
print(a.dtype)
# 初始化一个3*5的零矩阵,使用np.zeros()函数,但是要注意,传参需要是元组形式,即(m,n)的形式
# 默认元素的形式是float形式
a = np.zeros((3, 5))
print(a)
# 构造全一三维矩阵
# 可以自定义类型,使用dtype= 有若干类型,同样对维度的传参是一个元组
b = np.ones((2, 3, 4), dtype=np.int32)
print(b.shape)
# 构造一个等差list,传参注意依旧是左闭右开
# 如下示例,构造等差为5的list,范围为[10,30),所以生成的list为[10,15,20,25],不包括30
c = np.arange(10, 30, 5)
print(c)
print(np.arange(0, 2, 0.3))
print(c.reshape(2, 2))
# 构造一个随机矩阵,具有默认范围
d = np.random.random((2,3))
print(d)


# np.linspace()
# 建立一个数组,类似np.arange()函数的功能,产生按等差递增的一个数组,左右区间都闭合
# 如示例,该数组从0开始,到为2*pi,等差地共产生100个值
from numpy import pi
a = np.linspace(0, 2*pi, 100)
print(a)
print(a.shape)
print(a.dtype)
print(a.reshape(4, 25))
# np.sin(a) 对a中每个元素取正弦,同理np.cos(a)
print(np.linspace(0, 2, 3))
print(np.sin(np.linspace(0, 2, 3)))


# 算数操作
a = np.array([20, 30, 40, 50])
b = np.arange(0,4,1)
print(a)
print(b)
# minus,减数和被减数维数一样就是对应元素相减
c = a - b
print(c)
# minus,被减数中每个元素减1
c = c - 1
print(c)
# 乘方,m中每个元素乘n次方,m**n
print(b**2)
# 比较运算,m>n,对m中每个元素与n比较,判定成功返回True,错误返回False
print(a<35)

# the matrix product can be performed using the dot function or method
# 矩阵乘法有两种
# m*n即为m和n的元素在对应位置上相乘,要求m和n具有相同的维数
# m.dot(n)以及np.dot(m,n)为m和n做点乘,即正常的矩阵乘法。维数m为a*b,n为b*c
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))

# 求数组元素的指数和开方
# np.arange()默认是int32
# np.linspace()默认是float64
a = np.arange(1, 4, 1)
b = np.linspace(1, 4, 4)
print(a)
print(b)
print(np.exp(a))
print(np.sqrt(b))


#
# 矩阵操作
# np.floor(a),对a中的元素向下取整,但是取整后的结果精度不变,不会强制变为int32
a = np.floor(10 * np.random.random((3, 4)))
print(a)

# 若将向量排列为m*n的矩阵,使用a.reshape(m,n)就可
# 若要将矩阵拉成一个向量,需要使用a.ravel(),无参数
b = a.ravel()
print(b)
# 还可以将向量或矩阵a使用a.shape=(m,n)将其变为m*n的矩阵,注意在函数调用上和a.reshape(m,n)不太相同,reshape不能当左值
b.shape = (6, 2)
print(b)

m = 10*np.random.random((3, 4))
m = np.floor(m)
print(m)
m.shape = (6, 2)
print(m)
# 获得转置矩阵,貌似向量的转置不太行?
print(m.T)

# 在使用a.reshape(m,n)时,其中一维可以被指定为负数
# 因为对于二维矩阵来讲,只要一个维大小确定了,那么第二个维度就自动确定了,所以就可以设置为负数
print(m.reshape(-1, 3))
print(m.reshape(3, -1))
# 在n维矩阵中也同样适用,仅指定其中n-1维即可
a = np.random.random((3, 4, 5))
a = np.floor(10*a)
print(a.shape)
a.shape = (3,5,-1)
print(a.shape)

# 矩阵拼接
# 矩阵横着拼接,stack表示堆起来,h表示horizonal,使用np.hstack((a,b,c,等等))的形式,注意使用np.stack()时,参数为元组形式,元素类型会调整相同
# 矩阵竖着拼接,stack表示堆起来,v表示vertical,使用np.vstack((a,b,c,等等))的形式,同样注意参数为元组
a = np.floor(10*np.random.random((2, 2)))
b = np.floor(10*np.random.random((2, 2)))
c = np.ones((2, 2), dtype=int)
print(a)
print(b)
print(c)
print('---------')
print(np.hstack((a, b, c)))
print(np.vstack((a, b, c)))

# 矩阵拆分
# 和矩阵拼接道理相同,可以按行拆分也可以按列拆分
# 水平方向拆分,np.hsplit(a,3),矩阵a水平切分成3个
# 垂直方向拆分,np.vsplit(a,3),矩阵a垂直拆分成三个
a = np.floor(10*np.random.random((2, 12)))
a = a.astype(int)
print(a)
print('---------')
print(np.hsplit(a, 3))
print(np.vsplit(a, 2))
# 也可以指定矩阵拆分的位置,比如在二维矩阵中,在第n列和第n列各切一刀从而获得拆分的结果
# 同样使用np.hsplit() 和np.vsplit(),不同之处为参数多了一个元组,在元组内选择的是切分位置,注意矩阵下标从0开始,每个切片左闭右开
# 当采用如下切法时,将列切为[0,3],[3,4),[4,5),[5,11)
print(np.hsplit(a, (3, 4, 5)))
b = np.floor(10*np.random.random((4, 2)))
b = b.astype(int)
print(np.vsplit(b, (2, 3)))


# 不同复制操作的对比
# 第一种复制操作,等号赋值,直接把一个变量赋值给另外一个变量
# 这种复制,如果对一个变量进行修改,则另外一个变量也会跟着被修改
# 因为在这种复制模式下,不同变量名字实际指向的是同样的变量
# 因此 b is a 是 True,因为本质不变,id(a)和id(b)也相同
a = np.arange(12)
b = a
print(b is a)
b.shape = (3, 4)
print(id(a))
print(id(b))
# 第二种复制操作,view()赋值
# 这种复制操作下,a和c指向的是不同的东西,但是它们共用了一堆值
# 改变c的形状并不会改变a的形状
# c和a的id也并不相同
# 但是,改变c中的某个值,a中的值会发生变化
print('---------')
c = a.view()
print(c is a)
c.shape = (2, 6)
print(a.shape)
print(c.shape)
c[0, 4] = 1234
print(a)
print(id(a))
print(id(c))
# 第三种复制操作
# 使用a.copy()操作,只有这种操作,才能实现深复制,使得指向的值不同
# the copy method makes a complete copy of the array and its data
d = a.copy()
print(d is a)
d[0, 0] = 9999
print(d)
print(a)



# 查找索引和排序问题
# 首先构造一个5*4的矩阵
data = np.sin(np.arange(20)).reshape(5, 4)
print(data)
# 查找每列的最大值对应的下标索引,使用a.argmax(axis=0),若令参数axis=1,则查找每行最大值对应的索引
ind = data.argmax(axis=0)
print(ind)
# 用索引值找最大值,二维矩阵data.shape[1]为行数,data.shape[0]为列数
data_max = data[ind, range(data.shape[1])]
print(data_max)

# 行列扩展
# 构造一个数组,左闭右开,有四个元素
a = np.arange(0, 40, 10)
print(a)
# 行扩展为原来的2倍,列扩展为原来的3倍
b = np.tile(a, (2, 3))
print(b)


# 排序
a = np.array([[4, 3, 5],
              [1, 2, 1]])
print(a)
# sort默认从小到大排序,axis=1为对每行进行排序
b = np.sort(a, axis=1)
print(b)
# 给出当元素从小到大排列时的下标索引,如c输出[2,3,1,0]
a = np.array([4, 3, 1, 2])
c = np.argsort(a)
print(c)
print(a[c])

结论

代码都是亲自跑过的,注释也尽量写得通俗易懂一些,如果有什么问题的话欢迎和我交流谢谢。

发布了1 篇原创文章 · 获赞 0 · 访问量 48
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览