yiruia的个人博客分享 http://blog.sciencenet.cn/u/yiruia

博文

Day27 numpy数组_基本操作

已有 2527 次阅读 2020-5-24 19:32 |系统分类:科研笔记

一、numpy学习

1、为什么学习numpy?

快速、方便、科学计算的基础库

2、什么是numpy?

一个在python中做科学计算的基础库,重在数值计算,也是大部分python科学计算库的基础库,多用在大型、多维数组上执行数值运算。

二、numpy的基础知识

1、numpy创建数组(矩阵)

import numpy as np
t3 = np.arange(10) 
print(t3) #[0 1 2 3 4 5 6 7 8 9]
print(type(t3)) # <class 'numpy.ndarray'>
t4 = np.arange(2,10,2)
print(t4) # [2 4 6 8]
print(t4.dtype) # int32

2、数据类型的操作

(1)指定创建的数组的数据类型

numpy中的布尔类型

#numpy中的布尔类型
import numpy as np
a = np.array([1,0,1,0],dtype=np.bool) #或者使用dtype='?'
print(a) #[ True False  True False]
print(a.dtype) #bool
# # 修改数组的数据类型
print(a.astype("i1")) #或者使用a.astype(np.int8)
# # 修改浮点型的小数位数:
t4 = np.array(range(1,4),dtype=float) #数据类型是可以指定的
print(t4)
print(t4.dtype)
# #修改数据类型,astype
t6 = t4.astype("int8")
print(t6) # [1 2 3]
print(t6.dtype) #int8
import random
# # numpy中的小数
t7=np.array([random.random() for i in range(10)])
print(t7)
t8 = np.round(t7,2) #保留几位小数
print(t8)

(2)数组的形状

.shape查看数组的形状

import numpy as np
t1 = np.arange(12)
print(t1) # 列表[ 0  1  2  3  4  5  6  7  8  9 10 11]
# .shape查看数组的形状
print(t1.shape) # 元组,(12,)
t2 = np.array([[1,2,3],[4,5,6]])
print(t2)
# [[1 2 3]
#  [4 5 6]]
print(t2.shape) #(2, 3)
t3 = np.array([[[1,2,3],[4,5,6]],[[10,11,12],[13,14,15]]])
print(t3)
#[[[ 1  2  3]
 #  [ 4  5  6]]
 # 
 # [[10 11 12]
 #  [13 14 15]]]
print(t3.shape) #(2, 2, 3)

.reshape该表数组的形状,shape[0]表示数组的行数,shape[1]表示数组的列数

# reshape 改变数组的形状
t4 = np.arange(12)
print(t4.shape) #(12,)
print(t4.reshape(3,4))
#[[ 0  1  2  3]
 # [ 4  5  6  7]
 # [ 8  9 10 11]]
t5 = np.arange(24).reshape((2,3,4))
# print(t5) # 第一个指块数,第二个是块中的行数,第三个是块中的列数
print(t5.reshape((4,6))) # 有返回值,不会改变数值本身,即t5本身不变
print(t5)
t5 = np.arange(24).reshape((2,3,4))
t5 = t5.reshape((4,6)) #想让数据发生改变要对t5重新赋值
print(t5)
# 变成一维的
print(t5.reshape((24,))) #元组中有1个值表示一维,2个值二维,以此类推
print(t5.reshape(24,1)) # 24行*1列
print(t5.shape[0]) #4
print(t5.shape[1]) #6
t6 = t5.reshape((t5.shape[0]*t5.shape[1])) # [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
print(t6)
print(t5.flatten()) # 非常快速的直接把数组展开 #[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

三、数组和数组的计算

numpy中的广播性质,所有数值均能加/减/乘/除

t5 = np.arange(24).reshape((4,6))
print(t5)
print(t5+2) #t5中的每个数值均加2
print(t5*2)# t5中的每个数值均乘以2
# 0/0=nan(not a number),1/0=inf
t6 = np.arange(100,124).reshape((4,6))
print(t6)
print(t5+t6) # 形式完全相同的两数组可以直接相加
t7 = np.arange(0,6)
print(t5)
print(t7)
print(t5-t7)

以上均为广播机制。

广播原则:

(1)如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为他们是广播兼容的,广播会在缺失和(或)长度为1 的维度上进行。怎么理解呢?

可以把维度指的是shape所对应的数字个数,那么问题来了:

shape为(3,3,3)的数组能够和(3,2)的数组进行计算么?不能

shape为(3,3,2)的数组能够和(3,2)的数组进行计算么?能

(2)轴

在numpy中可以理解为方向,使用0,1,...数字表示,对于一个一维数组,只有0个轴,对于2维数组,有0轴和1轴,对于三维数组(shape(2,2,3)),有0,1,2轴。

那么问题来了:

在前面的知识中,轴在哪里?

回顾np.arange(0,10).reshape((2,5)),reshape中表示0轴长度(包括数据的条数)为2,1轴长度为5,2*5公10个数据。

(3)numpy读取数据

csv,comma-separated value,逗号分隔值文件

显示:表格状态

源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录

由于csv便于展示,读取和写入,所以很多地方也是用csv格式存储和传输中小型的数据

为方便教学,我们经常操作csv格式的文件,但是操作数据库中的数据也是很容易实现的。

np.loadtxt(frame,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)

frame:文件、字符串或产生器,可是实现gz或bz压缩文件

dtype:数据类型,可选,csv的字符串以什么数据类型读入数组中,默认np.float

delimiter:分隔字符串,默认是任何空格,改为逗号

skiprow:跳过前x行,一般跳过第一行表头

usecol:读取指定的列、索引和元组类型

unpack:如果True,读入属性将分别写入不同数组变量(转置),False读入数据只写一个数组变量,默认False


例子:现在有一个英国和美国各来自youtube100多个视频的点击,喜欢,不喜欢,评论数量(['views','likes','dislikes','comment-total'])的csv,运用刚刚所学的知识,我们尝试对其进行操作。

us_file_path = 'E:\paper\用户画像\小木虫论文代码\协同过滤算法练习\训练模型前数据处理代码\用户信息评分表'
uk_file_path = 'filename2'
t1 = np.loadtxt(us_file_path,delimiter=',',dtype='int')
print(t1)

其中,添加delimiter和dtype以及unpack的效果

delimiter:指定边界符号是什么,不指定会导致每行数据为一个整体的字符串而报错

dtype:默认情况下对于较大的数据会将其变成科学计数的形式。

那么,unpack的效果呢?

unpack:默认是False(0),默认情况下,有多少条数据就会有多少行,为True(1)的情况下,每一列的数据会组成一行,元数据有多少列,加载出来的数据会有多少行,相当于转置的效果。转置是一种变换,目的就是为了更方便的去处理数据。

t2 = np.arange(24).reshape((4,6))
# 转置的方式:
print(t2)
print(t2.transpose())
print(t2.T)
print(t2.swapaxes(1,0))

那么,结合之前所学的matplotlib把美国和英国的数据呈现出来?

看到这个问题,我们应该考虑什么?

1、我们想要反映什么样的结果,解决什么样的问题?

2、选择什么样的方式呈现

3、数据好需要做什么样的处理

4、写代码

(4)numpy的索引和切片

对于刚刚加载出来的数据,我如果想选择其中的某一列(行),我们应该怎么做呢?

其实操作很简单,和python中的列表操作一样

us_file_path = r'E:\paper\用户画像\小木虫论文代码\协同过滤算法练习\训练模型前数据处理代码\用户兴趣评分表.csv'
uk_file_path = 'filename2'
t1 = np.loadtxt(us_file_path,delimiter=',',dtype='float')
print(t1)
print('*'*100)
# 取行
print(t1[2])
#取连续的多行
print('*'*100)
print(t1[2:])
#取不连续的多行
print('*'*100)
print(t1[[2,8,10]])

#取行,逗号前表示行,逗号后表示列
print(t1[1,:])
print('*'*100)
print(t1[2:,:])
print('*'*100)
print(t1[[2,10,3],:])

# 取列,逗号前表示行,逗号后表示列
print('*'*100)
print(t1[:,0])
print('*'*100)

# 取连续的多列
print(t1[:,2:])
print('*'*100)
print(t1[:,[0,2]])

# 取第一行第二列的值
print('*'*100)
print(t1[2,1])
print(type(t1[2,1]))

# 取多行和多列,取第3行到第5列,第1列到第2列的结果,取的是行和列交叉点的位置
print('*'*100)
print(t1[2:5,0:2])
print(type(t1[3:5,0:2]))

# 取多个不相邻的点
print('*'*100)
c = t1[[0,1,1],[0,0,1]] #(0,0),(1,0),(1,1)
print(c)
c = t1[[0,1],[0,0]] #(0,0),(1,0)
print(c)#了解一下就可以

(5)numpy中的数值修改

修改行列的值(先取到再赋值),我们能够很容易的实现,但是如果条件更复杂呢?比如我们想把t中小于10的数字替换为3,大于10的替换为10,应该怎么做?

print(t1<10)
t1[t1<10]=3 #对为True的值进行赋值
t1[t1>10]=10
print(t1)

1)numpy中的三元运算符

t = np.arange(24).reshape((4,6))
print(t)
print(np.where(t<10,0,10)) #numpy中的三元运算符,t<10取0,t>10取10

如果我们想把t中小于10的数字替换为0,大于20的替换为20应该怎么做?

print(np.where(t<10,0,20))

2)numpy中的clip(裁剪)

# # numpy中的clip(裁剪)
t = np.arange(24).reshape((4,6))
print(t.clip(10,18)) #观察左边的操作:小于10的替换为10,大于18的替换为18,但是nan没有被替换,那nan是什么
# t[3,3] = np.nan
# print(t) # ValueError: cannot convert float NaN to integer会报错
t2 = t.astype(float) #改变t的数据类型为浮点型
t2[3,3] = np.nan
print(t2)

3)数组的拼接

现在我们希望把之前案例中两个国家的数据放在一起研究分析,应该怎么做?

t1 = np.arange(12).reshape((2,6))
t2 = np.arange(12,24).reshape((2,6))
print(t1)
print(t2)
t3 = np.vstack((t1,t2)) # 竖直拼接(vertically)
print(np.hstack((t1,t2))) #水平拼接(hertically)

4)数组的行列交换

数组水平或者竖直拼接很简单,但是拼接之前应该注意什么?

竖直拼接的时候:每列代表的意义相同!否则牛头不对马嘴

如果每一列的意义不同,这时候应该交换某一组数的列,让其和另外一类相同

那么问题来了,如何交换某个数组的行或列呢?

t1 = np.arange(12).reshape((4,3))
print(t1)
print('*'*100)
t1[[1,0],:]=t1[[0,1],:] #行交换
print(t1)
print('*'*100)
t1[:,[1,0]]=t1[:,[0,1]] #列交换
print(t1)

动手,现在希望把之前案例中两个国家的数据放在一起来研究分析,同时保留国家的信息(每条数据的国家来源),应该怎么办?

加载国家数据

us_file_path = r'E:\paper\用户画像\小木虫论文代码\协同过滤算法练习\训练模型前数据处理代码\用户兴趣评分表.csv'
uk_file_path = r'E:\paper\用户画像\小木虫论文代码\协同过滤算法练习\训练模型前数据处理代码\用户兴趣评分表.csv'

us_data = np.loadtxt(us_file_path,delimiter=',',dtype='float')
uk_data = np.loadtxt(uk_file_path,delimiter=',',dtype='float')

# 添加国家信息
#构造全为0的数据
zeros_data = np.zeros((us_data.shape[0],1)).astype(int)
ones_data = np.ones((us_data.shape[0],1)).astype(int)

# 分别添加一列全为0,1的数组
us_data = np.hstack((us_data,zeros_data))
uk_data = np.hstack((uk_data,ones_data))

#拼接两组数据
final_data = np.vstack(us_data,uk_data)
print(final_data)
获取最大值和最小值的位置
t = np.eye(4)
print(t)
print(np.argmax(t,axis=0)) #每列最大值的位置
print(np.argmin(t,axis=1)) #每行最小值的位置
t[t==1] = -1
print(t)
print(np.argmax(t,axis=0))
print(np.argmin(t,axis=1))
# 创建一个全0的数组:np.zeros((3,4))
print(np.zeros((3,4)))
# 创建一个全为1的数组:np.ones((3,4))
print(np.ones((3,4)))
#创建一个对角线为1的正方形数组(方阵):np.eye(3)
print(np.eye(3))




https://wap.sciencenet.cn/blog-3405644-1234741.html

上一篇:Day26 数据分析
下一篇:Day29 pandas_Series和读取外部数据
收藏 IP: 223.91.39.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-24 06:36

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部