目录
2. array/asarray 函数对列表 list 和 元组的转换
3. 一维数组 ndarray 能使用列表 list 的所有索引方法
Python 数据分析三剑客:
1. numpy 模块
2. pandas 模块
3. matpotlib 模块
NumPy(Numerical Python的简称)是是Python 数据分析三剑客之一,它是高性能科学计算和数据分析的基础包。NumPy最重要的一个特点就是其N维数组对象(即ndarray),该对象是一个快速而灵活的大数据集容器。可以利用这种数组对整块数据执行一些数学运算,比python自带的数组以及元组效率更高,其语法跟变量元素之间的运算一样,无需进行循环操作。
在使用python进行数据分析的过程中,我们大部分时候是不会直接使用numpy包,而是其他包要用到numpy,例如pandas 模块就是基于 numpy, 是 numpy 的升级版本。可以说numpy是整个python数据分析工作的基石。
一、ndarray 和 列表 list 的比较
1. 计算能力和效率差异
两者形式上非常相似,最根本的区别就是列表只是一种数据的容器,不具有任何计算能力!
举例说明,先创造一个h、w 两个列表,通过使用%%time可以看出来创建这么大的列表还是花了不少时间的。
%%time
# 导入第三方模块
import numpy as np
import random
# 伪造数据
h = [] # h 代表高度
w = [] # w 代表重量
for i in range(10000000):
h.append(random.randint(153,180))
w.append(random.uniform(51,88))
运行结果是
Wall time: 16.9 s
如果想对h、w 做一些计算工作,例如算出人体的 bmi 值,在没有接触数据分析模块之前,如下面 代码,代码可以称为简洁。
%%time
# 将会给出cell的代码运行一次所花费的时间 %time 则是给出一行的执行时间
bmi = []
for i in range(10000000):
bmi.append(w[i]/(h[i]/100) ** 2)
但是请注意,通过%%time提供的数据来看,它花的时间不容小觑
Wall time: 5.63 s
那如果用 Numpy 来实现这个功能呢
H = np.array(h) # 转化成数组
W = np.array(w) # 转化成数组
%%time
BMI = W/(H/100)**2
运行结果是,请注意单位一下子从s到ms,这在性能上完全不是一个数量级的。
Wall time: 89.8 ms
2. array/asarray 函数对列表 list 和 元组的转换
#借助于array函数可以将列表或元组转换为数组
a=list(range(10))
b=tuple(range(10))
a_array=np.array(a)
b_array=np.array(b)
print(type(a))
print(type(b))
print(type(a_array))
print(type(b_array))
运行结果是
<class 'list'> <class 'tuple'> <class 'numpy.ndarray'> <class 'numpy.ndarray'>
numpy.array的语法格式是numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
此外还有numpy.array,numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。
numpy.asarray(a, dtype = None, order = None)
参数 | 描述 |
---|---|
a | 任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组 |
dtype | 数据类型,可选 |
order | 可选,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。 |
3. 一维数组 ndarray 能使用列表 list 的所有索引方法
array 可以使用我们熟悉的索引方法和切片,举例代码
a.append(12)
print(a[5:])
a.clear()
print(a)
print(a_array[1])
print(a_array[:5])
print(a_array[:])
运行结果
[5, 6, 7, 8, 9, 12] []1 [0 1 2 3 4] [0 1 2 3 4 5 6 7 8 9]
4. 一维数组有更多强大的方法
数组还有列表没有的索引方法
4.1 间隔索引
代码段
b=list(range(10))
b_array=np.array(b)
print(b_array[[1,2,3]])
print(b[[1,2,3]])
运行结果可以清楚的看到对于列表 b 提示“TypeError: list indices must be integers or slices, not list”,而对于一维数组 b_array 通过[[index1,index2...]]的方式,实现了多数值间隔索引。
[1 2 3]--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-12-d90ec075f85c> in <module> 2 b_array=np.array(b) 3 print(b_array[[1,2,3]]) ----> 4 print(b[[1,2,3]]) TypeError: list indices must be integers or slices, not list
4.2 布尔索引
布尔索引,又叫逻辑索引,可以很快很方便的实现对数据进行判断,代码简洁。
b=list(range(10))
b_array=np.array(b)
print("*"*40)
#找出b_array中小于5的数字
print(b_array <5) # 形成布尔值
print(b_array[b_array <5 ]) # 按照布尔值选出值
print("*"*40)
#找出奇数
print(b_array%2 == 1)# 形成布尔值
print(b_array[b_array%2 == 1]) # 按照布尔值选出值
#
运行结果
**************************************** [ True True True True True False False False False False] [0 1 2 3 4] **************************************** [False True False True False True False True False True] [1 3 5 7 9]
4.3 其余方法
a 作为列表有如下方法
而 a_array 有如下方法
我们先看看常用属性吧
print(b_array)
print(b_array.all()) #判断b_array 每个值是否是True
print(b_array.any()) #判断b_array 任意一个值是否是True,是的话为True
print(b_array.argmax())#最大参数
print(b_array.argmin())#最小参数
print("*"*50)
print(b_array.ndim) #秩,即轴的数量或维度的数量
print(b_array.shape) #数组的维度,对于矩阵,n 行 m 列
print(b_array.size) #数组元素的总个数,相当于 .shape 中 n*m 的值
print("*"*50)
print(b_array.dtype) # ndarray 对象的元素类型
print(b_array.itemsize) # ndarray 对象中每个元素的大小,以字节为单位
print(b_array.flags) # ndarray 对象的内存信息
print("*"*50)
print(b_array.real) # ndarray 元素的实部
print(b_array.imag) # ndarray 元素的虚部
运行结果
[0 1 2 3 4 5 6 7 8 9] False True 9 0 ************************************************** 1 (10,) 10 ************************************************** int32 4 C_CONTIGUOUS : True F_CONTIGUOUS : True OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False UPDATEIFCOPY : False ************************************************** [0 1 2 3 4 5 6 7 8 9] [0 0 0 0 0 0 0 0 0 0]
关于属性 flags 有如下不同的分类:
属性 | 描述 |
---|---|
C_CONTIGUOUS (C) | 数据是在一个单一的C风格的连续段中 |
F_CONTIGUOUS (F) | 数据是在一个单一的Fortran风格的连续段中 |
OWNDATA (O) | 数组拥有它所使用的内存或从另一个对象中借用它 |
WRITEABLE (W) | 数据区域可以被写入,将该值设置为 False,则数据为只读 |
ALIGNED (A) | 数据和所有元素都适当地对齐到硬件上 |
UPDATEIFCOPY (U) | 这个数组是其它数组的一个副本,当这个数组被释放时,原数组的内容将被更新 |
二、二维数组
1. 二维数组概念介绍
2. 创建二维数组
2.1 从列表和元组转换
同一维数组,二维数组也可以从列表和元组转换而来。
# 基于嵌套列表创建二维数组
arr1 = np.array([[1,3,5,7],
[2,4,6,8],
[11,13,15,17],
[12,14,16,18],
[100,101,102,103]])
# 基于嵌套元组创建二维数组
arr2 = np.array(((8.5,6,4.1,2,0.7),(1.5,3,5.4,7.3,9),
(3.2,3,3.8,3,3),(11.2,13.4,15.6,17.8,19)))
# 二维数组的打印结果
print(arr1,'\n')
print(arr2)
运行结果是
[[ 1 3 5 7] [ 2 4 6 8] [ 11 13 15 17] [ 12 14 16 18] [100 101 102 103]] [[ 8.5 6. 4.1 2. 0.7] [ 1.5 3. 5.4 7.3 9. ] [ 3.2 3. 3.8 3. 3. ] [11.2 13.4 15.6 17.8 19. ]]
2.2 使用 numpy.empty
也可以使用numpy.empty来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组
格式如 numpy.empty(shape, dtype = float, order = 'C')
shape 即数组形状
dtype 指 数据类型,可以选择
order,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。
代码段如下:
new_array=np.empty([2,3],int)
print(new_array)
new_array=np.empty([2,3],bool)
print(new_array)
new_array=np.empty([2,3],complex)
print(new_array)
运行结果如下:
[[682486592 424 0] [ 0 1 4390973]] [[ True True True] [ True False False]] [[9.00063688e-312+3.16202013e-322j 0.00000000e+000+0.00000000e+000j 0.00000000e+000+1.70317226e-051j] [2.95385063e+179+3.50444959e-033j 1.46366170e-047+5.99406363e-066j 1.50161777e-076+9.76299584e+165j]]#数据是随机的,因为没有初始化
2.3 使用 numpy.zeros、numpy.ones
也可以使用 numpy.zeros 来创建指定大小的数组,数组元素以 0 来填充:
代码段如下:
new_array=np.zeros([4,5],dtype=int)
print(new_array)
new_array=np.zeros([2,4],dtype=bool)
print(new_array)
new_array=np.zeros([2,4],dtype=complex)
print(new_array)
运行结果:
[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]] [[False False False False] [False False False False]] [[0.+0.j 0.+0.j 0.+0.j 0.+0.j] [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
类似的 numpy.ones 创建指定形状的数组,数组元素以 1 来填充,就不再赘述了
2.4 使用 numpy.arrange
numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,函数格式如下:
numpy.arange(start, stop, step, dtype)
根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。
参数说明:
参数 | 描述 |
---|---|
start | 起始值,默认为0 |
stop | 终止值(不包含) |
step | 步长,默认为1 |
dtype | 返回ndarray 的数据类型,如果没有提供,则会使用输入数据的类型。 |
3. 二维数组的数据读取
a) 在二维数组中,位置索引必须写成[rows,cols]的形式,方括号的前半部分用于锁定二 维数组的行索引,后半部分用于锁定数组的列索引;
b) 如果需要获取二维数组的所有行或列元素,那么,对应的行索引或列索引需要用英文 状态的冒号表示;
代码段如下
# 二维数组的打印结果
print(arr1,'\n')
print(arr1[1]) # 选择出第二行
print(arr1[1,2]) # 选择出第二行,第三列的数据
print(arr1[1,:]) # 选择出第二行
print(arr1[:,3]) # 选择出第四列
print(arr1[:,[2,3]]) # 选择出第三、四列(间隔索引)
运行结果如下
[[ 1 3 5 7] [ 2 4 6 8] [ 11 13 15 17] [ 12 14 16 18] [100 101 102 103]] [2 4 6 8] 6 [2 4 6 8] [ 7 8 17 18 103] [[ 5 7] [ 6 8] [ 15 17] [ 16 18] [102 103]]
4. 二位数组的常见属性
如一维数组,见下方代码段
print(arr1.all()) #判断b_array 每个值是否是True
print(arr1.any()) #判断b_array 任意一个值是否是True,是的话为True
print(arr1.argmax())#最大参数
print(arr1.argmin())#最小参数
print("*"*50)
print(arr1.ndim) #秩,即轴的数量或维度的数量
print(arr1.shape) #数组的维度,对于矩阵,n 行 m 列
print(arr1.size) #数组元素的总个数,相当于 .shape 中 n*m 的值
print("*"*50)
print(arr1.dtype) # ndarray 对象的元素类型
print(arr1.itemsize) # ndarray 对象中每个元素的大小,以字节为单位
print(arr1.flags) # ndarray 对象的内存信息
print("*"*50)
print(arr1.real) # ndarray 元素的实部
print(arr1.imag) # ndarray 元素的虚部
运行结果为
True True 19 0 ************************************************** 2 (5, 4) 20 ************************************************** int32 4 C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False UPDATEIFCOPY : False ************************************************** [[ 1 3 5 7] [ 2 4 6 8] [ 11 13 15 17] [ 12 14 16 18] [100 101 102 103]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]
5. 二维数组的常用方法
将在下一章节Numpy 模块-常用函数_一分耕耘一分收获-CSDN博客_numpy 函数中继续讲