Python数据分析之numpy数组全解析
1 什么是numpy
numpy是一个在Python中做科学计算的基础库,重在数值计算,也是大部分Python科学计算库的基础库,多用于大型、多维数据上执行数值计算。
在NumPy 中,最重要的对象是称为 ndarray 的N维数组类型,它是描述相同类型的元素集合,numpy所有功能几乎都以ndarray为核心展开。ndarray 中的每个元素都是数据类型对象(dtype)的对象。ndarray 中的每个元素在内存中使用相同大小的块
2 numpy数组创建
创建Numpy数组一般有三种方法:
(1)通过传入可待跌对象创建,我将之称为基本方法
(2)使用Numpy内部功能函数,内部方法
(3)使用特殊的库函数,特殊方法
2.1 基本方法:np.array()
基本方法是通过给numpy提供的一些函数中传入可迭代对象来创建数组,这种方法通常是在已知所有元素的情况下使用。numpy中实现这种功能的函数包括:np.array()、np.arange()、np.line(),:
>>> np.array([0, 1, 2, 3, 4]) # 接收一个list作为参数
array([0, 1, 2, 3, 4])
>>> np.array([[11, 12, 13],[21, 22, 23]]) # 创建一个2*3的数组
array([[11, 12, 13],
[21, 22, 23]])
>>> np.array((0, 1, 2, 3, 4)) # 接收一个tuple作为参数
array([0, 1, 2, 3, 4])
np.array()方法可以在创建数组的同时指定数据类型:
>>> np.array([0, 1, 2, 3, 4], dtype=float)
array([0., 1., 2., 3., 4.])
甚至还可以接受range()返回的可迭代对象作为参数:
>>> np.array(range(5))
array([0, 1, 2, 3, 4])
>>> np.array(range(10, 20, 2))
array([10, 12, 14, 16, 18])
2.2 通用方法:np.ones()、np.zeros()、np.eye()
通用方法指的是numpy中提供的arange()、ones()、zeros()、eye()、full()等方法,这些方法可以按照某种规则生成一个数组,并不需要传入已知的可迭代对象。
(1)np.arange()
上面我们将range()函数结果传递给np.array(),np.arange()实现的就是这个功能,所以说,np.arange()就是numpy中的range()方法。
>>> np.arange(5)
array([0, 1, 2, 3, 4])
>>> np.arange(10, 20, 2)
array([10, 12, 14, 16, 18])
(2)np.linspace()
np.linspace()方法以等间距的形式对给定的两数进行划分来创建数组:
>>> np.linspace(10, 20, 5) # 将10到20间的数等距取5个
array([10. , 12.5, 15. , 17.5, 20. ])
(3)np.ones()
创建一个元素值全为1的数组,接收一个list或者tuple作为参数
>>> np.ones([2]) # 创建一个一维数组
array([1., 1.])
>>> np.ones([2, 2]) # 创建一个2维数组
array([[1., 1.],
[1., 1.]])
>>> np.ones([2, 2, 2])
array([[[1., 1.],
[1., 1.]], [[1., 1.],
[1., 1.]]])
(4)np.zeros()
创建一个元素值全为0的数组,接收一个list或者tuple作为参数
>>> np.zeros([3])
array([0., 0., 0.])
>>> np.zeros([3, 3])
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
(5)np.random.random()
创建一个元素为0到1之间随机数的数组,接收一个list或者tuple作为参数:
>>> np.random.random((3, 3))
array([[0.19414645, 0.2306415 , 0.08072019],
[0.68814308, 0.48019088, 0.61438206],
[0.5361477 , 0.33779769, 0.38549407]])
既然有random()方法,那么就会有randint()方法,也就是取随机整数的方法,不过这个randint()方法参数形式更random()不太一样,具体请看下面实例:
>>> np.random.randint(1, 10, 3) # 从1到10之间随机取3个整数创建数组
array([6, 4, 6])
(6)np.eye()
创建一个从左上角到右下角的对角线上全为1,其余元素全为0的数组(单位矩阵)。注意,np.eye()的参数可不再是list或者tuple了。
>>> np.eye(3, 3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
(7) np.full()
np.full()函数可以创建一个填充给定数值的数组,第一个参数是定义数组形状的list或tuple,第2个参数是需要填充的数值:
>>> np.full((2, 3), 3) # 创建一个2*3的数组,所有元素都填充3
array([[3, 3, 3],
[3, 3, 3]])
2.3 读取外部数据
numpy也支持从外部读取数据来创建数组,例如从硬盘中读取csv、txt等文件来创建数组。np.genfromtxt()是numpy中读取文件的一个方法,例如在当前目录下有一个data.csv文件,文件内容为:
id,height,length
1,100,101
2,200,230
3,300,350
通过numpy读取:
>>> np.genfromtxt('data.csv',delimiter=',',skip_header=1)
array([[ 1., 100., 101.],
[ 2., 200., 230.],
[ 3., 300., 350.]])
读取外部数据的方法不止np.genfromtxt(),还有np.load(等,但numpy读取外部数据的应用情况其实并不多,这里不再细说。
3 numpy中数组的数据类型
作为一个强大的科学计算库,numpy中支持的数据类型远不止Python原生的几种数据类型。如下所示为numpy中支持的数据类型:
数据类型
|
描述
|
bool_
|
布尔(True或False),存储为一个字节
|
int_
|
默认整数类型(与Clong相同;通常是int64或int32)
|
INTC
|
与Cint(通常为int32或int64)相同
|
INTP
|
用于索引的整数(与Cssize_t相同;通常是int32或int64)
|
INT8
|
字节(-128至127)
|
INT16
|
整数(-32768至32767)
|
INT32
|
整数(-2147483648至2147483647)
|
Int64的
|
整数(-9223372036854775808至9223372036854775807)
|
UINT8
|
无符号整数(0到255)
|
UINT16
|
无符号整数(0到65535)
|
UINT32
|
无符号整数(0到4294967295)
|
UINT64
|
无符号整数(0到18446744073709551615)
|
float_
|
float64的简写。
|
float16
|
半精度浮点:符号位,5位指数,10位尾数
|
FLOAT32
|
单精度浮点数:符号位,8位指数,23位尾数
|
float64
|
双精度浮点:符号位,11位指数,52位尾数
|
complex_
|
complex128的简写。
|
complex64
|
复数,由两个32位浮点数(实部和虚部)
|
complex128
|
复数,由两个64位浮点数(实部和虚部)
|
这些数据类型可以通过如np.bool_、np.float16等形式来调用,上文中提到过,创建数组时可以指定数据类型:
>>> a = np.array([0, 1, 0, 1], dtype=np.bool_)
>>> a
array([False, True, False, True])
可以通过numpy数组自带的dtype属性来查看数组的数据类型:
>>> a.dtype
dtype('bool')
为什么输出的类型是bool而不是bool_呢?因为numpy中后缀带下划线“_”的数据类型指向的就是Python原生的数据类型,也就是说,np.bool_与Python中的bool数据类型等效,np.float_与Python中的float类型等效。
当一个数组已经被创建,但是想要改变其数据类型,那就可以通过np.asdtype()方法:
>>> a.astype(np.int)
array([0, 1, 0, 1])
>>> a = np.random.random((2,2))
>>> a
array([[0.02914317, 0.645534 ],
[0.61839509, 0.64155607]])
>>> a.dtype
dtype('float64')
>>> a.astype(np.float16)
array([[0.02914, 0.6455 ],
[0.618 , 0.6416 ]], dtype=float16)
>>> a.dtype
dtype('float64')
4 numpy中数组的形状
numpy中数组使用与存放多维数据,所以,所谓数组的形状指的就是数据的维度大小,以及每一维度元素个数。我们可以通过数组自带的shape属性来查看形状信息:
>>> a = np.array([[2, 3, 4], [5, 6, 7]])
>>> a
array([[2, 3, 4],
[5, 6, 7]])
>>> a.shape # 查看形状属性
(2, 3)
可以看到,查看形状属性时返回的是一个元组,元素的长度代表数组的维度,元组每一个属性代表对应的维度的元素个数,(2,3)就表示第一个维度元素个数是2(两行),第二个维度长度是3(3列)。
在数组创建之后,数组的形状也是可以改变的。改变数组的形状通过数组的reshape()方法:
>>> a = np.ones((2, 12))
>>> a
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.]])
>>> a.shape
(2, 12)
>>> b = a.reshape(2, 3, 4)
>>> b
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.]]])
>>> b.shape
(2, 3, 4)
>>> b = a.reshape((2,3,4)) # 元组作为参数
>>> b
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.]]])
>>> b.shape
(2, 3, 4)
可以看到,np.reshape()方法可以同时传入多个描述形状的数字,也可以传入一个数组,当然,如果将形状改变为一维数组时,必须传入的是元组。另外需要注意,传入reshape方法的多个参数的乘积必须与改变前数组总长度相等,否则会报错。
numpy数组中专门提供了一个方法加你个数组转换为以为数组,那就是flatten()方法,这个方法在执行数组运算是非常有用:
>>> a = np.ones((2, 3))
>>> b = a.flatten()
>>> b
array([1., 1., 1., 1., 1., 1.])
>>> b.shape
(6,)
5 索引与切片
对数据使用时,不可避免要进行索引和切片,numpy在这一方面不可谓不强大。numpy数组中所有的索引都是从0开始的,我们可以根据索引来精确取数据。
5.1 按索引取值
下面所有实例都已下方数组a来展开:
>>> a = np.arange(36).reshape((4, 9))
>>> a
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8],
[ 9, 10, 11, 12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23, 24, 25, 26],
[27, 28, 29, 30, 31, 32, 33, 34, 35]])
(1)取一行
>>> a[1] # 取第二行数据
array([ 9, 10, 11, 12, 13, 14, 15, 16, 17])
(2)取连续多行数据
>>> a[:2] # 取前两行数据
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8],
[ 9, 10, 11, 12, 13, 14, 15, 16, 17]])
也可以加上步长:
>>> a[::2] # 每隔一行取一次
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8],
[18, 19, 20, 21, 22, 23, 24, 25, 26]])
>>> a[1:] # 取第2行后面所有行
array([[ 9, 10, 11, 12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23, 24, 25, 26],
[27, 28, 29, 30, 31, 32, 33, 34, 35]])
(3)取不连续多行数据
>>> a[[0,-1]] # 取第一行和最后一行
>>> a[[0,-1]]
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8],
[27, 28, 29, 30, 31, 32, 33, 34, 35]])
可以看到,对numpy根据索引进行取值的方法与Python中list索引取值方法类似,都是通过方括号里面传入索引取值,当需要对多维进行索引时,每一位数据之间用逗号隔开。
(4)取一列
>>> a[:,1] # 取第2列
array([ 1, 10, 19, 28])
(5)取连续多列
>>> a[:,1:3] # 取第2列到第3列
array([[ 1, 2],
[10, 11],
[19, 20],
[28, 29]])
(6)取不连续多列
>>> a[:,[0,3]] # 取第1列和第4列
array([[ 0, 3],
[ 9, 12],
[18, 21],
[27, 30]]))
(7)取连续多行多列
>>> a[1:3:,1:3] # 取第2、3行中的第2、3列
array([[10, 11],
[19, 20]])
(8)取多个不连续位置数据
看到这里你应该也明白了取行、取列的规律了,如果取不连续的多行多列呢?例如取第1、3行与第2、4列,你可能认为是a[[0, 2], [1, 3]],我们来看看:
>>> a[[0, 2], [1, 3]]
array([ 1, 21])
可见,返回的并不是预期的数据,而是第1行第2列、第3行第4列的数据,也就是(0,1)和(2,3)位置的数据。
从而我们可以得出结论,如果取第3行中第3列、第5列,第4行中第1列、第7列数据方法如下:
>>> a[[2,2,3,3],[2,4,0,6]] # 第3行中第3列、第5列,第4行中第1列、第7列数据
array([20, 22, 27, 33])
(9)取单个数据
>>> b = a[3,3]
>>> b
30
>>> type(b) # 取单个类型是返回的就是一个确切的numpy类型数值
<class 'numpy.int64'>
5.2 bool索引
(1)bool索引取值
numpy中提供了一些通用函数来实现通过bool条件判断实现按条件取值,使用这些通用方法,与使用对应的符号时等效的,符号与numpy通用方法对应关系如下:
运算符 | 对应的通用函数 |
== | np.equal |
!= | np.not_equal |
< | np.less |
<= | np.less_equal |
> | np.greater |
>= | np.greater_equal |
我们通过实例感受一下:
>>> a = np.arange(24).reshape((4,6))
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
>>> b = a<5 # bool索引选取
>>> b
array([[ True, True, True, True, True, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False]])
可以看到,在元素值小于5的位置上值为True,不满足条件的为False。
也可以使用通用函数实现:
>>> b = np.less(a,5) # 通用函数选取
>>> b
array([[ True, True, True, True, True, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False]])
对bool索引选取出来的结果全是True或者False,可能不是你想要的,可以进一步使用:
>>> a[b]
array([0, 1, 2, 3, 4])
所以我们可以直接刷选值:
>>> a[a<5]
array([0, 1, 2, 3, 4])
(2)三目元算
numpy中提供了一个where()方法来实现三目运算。where()方法接受三个参数,第一个参数是判断条件,第二个参数时时判断条件为真时数组中满足条件的元素将要替换的值,第三个参数是判断调价为假时不满足条件元素将要替换的值。
例如,将数组中所有满足元素值小于5的数值替换为0,不满足的元素值替换为1:
>>> a = np.arange(24).reshape((4,6))
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
>>> np.where(a<5, 0, 1) # 三目运算
array([[0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1]])
6 numpy中赋值、视图、深复制
(1)赋值
当对numpy数组进行赋值时,只是对同一个对象新建了一个引用,并不是建立新的对象,所以赋值前后的变量完全是同一对象,对其中一个引用修改时,所有引用都会生效:
>>> a = np.arange(12)
>>> b = a # 赋值
>>> a is b
True
>>> b.shape = (3, 4)
>>> b
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
(2)视图(切片、浅复制)
numpy中允许不同数组间共享数据,这种机制在numpy中称为视图,对numpy数组的切片和浅复制都是通过视图实现的。如果数组B是数组A的视图(view),则称A为B的base(除非A也是视图)。视图数组中的数据实际上保存在base数组中。
>>> a = np.arange(12)
>>> b = a.view() # 使用视图
>>> a is b
False
>>> b
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> b.shape = (3, 4) # 改变b的形状
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> b
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b[0] = 0
>>> a
array([ 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11])
>>> b
array([[ 0, 0, 0, 0],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
从上面代码中我们可以发现,a和b是不同的两个数组,改变b的形状对a不会有影响,但是改变b的数据之后,a的数据也会发现改变,说明a与b是共享数据的。
再来探索一些切片:
>>> a = np.arange(12)
>>> b = a[:] # 切片
>>> a is b
False
>>> b.shape = (3, 4)
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> b
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b[0] = 0
>>> a
array([ 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11])
>>> b
array([[ 0, 0, 0, 0],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
果然,切片效果与视图一致。
(3)深复制
深复制通过数组自带的copy()方法实现,深复制产生的数组与原数组时完全不同的两个数组对象,完全享有独立的内存空间,所有操作都不会相互影响。
>>> a = np.arange(12)
>>> b = a.copy()
>>> a is b
False
>>> b.shape = (3, 4)
>>> b[0] = 0
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> b
array([[ 0, 0, 0, 0],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
Python数据分析之numpy数组全解析的更多相关文章
- python数据分析工具 | numpy
Python中没有提供数组功能,虽然列表可以完成基本的数组功能,但并不是真正的数组,而且在数据量较大时,使用列表的速度回非常慢.因此,Numpy提供了真正的数组功能,以及对数据进行快速处理的函数.Nu ...
- python数据分析之numpy、matplotlib的使用
5.3 Python的科学计算包 - Numpy numpy(Numerical Python extensions)是一个第三方的Python包,用于科学计算.这个库的前身是1995年就开始开发的一 ...
- Python数据分析(二): Numpy技巧 (1/4)
In [1]: import numpy numpy.__version__ Out[1]: '1.13.1' In [2]: import numpy as np
- Python数据分析(二): Numpy技巧 (2/4)
numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性. 昨天晚上发了第一 ...
- Python数据分析(二): Numpy技巧 (3/4)
numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性. 昨天晚上发了第一 ...
- Python数据分析(二): Numpy技巧 (4/4)
numpy.pandas.matplotlib(+seaborn)是python数据分析/机器学习的基本工具. numpy的内容特别丰富,我这里只能介绍一下比较常见的方法和属性. 第一部分: ht ...
- python数据分析基础——numpy和matplotlib
numpy库是python的一个著名的科学计算库,本文是一个quickstart. 引入:计算BMI BMI = 体重(kg)/身高(m)^2假如有如下几组体重和身高数据,让求每组数据的BMI值: w ...
- Python数据分析之Numpy操作大全
从头到尾都是手码的,文中的所有示例也都是在Pycharm中运行过的,自己整理笔记的最大好处在于可以按照自己的思路来构建矿建,等到将来在需要的时候能够以最快的速度看懂并应用=_= 注:为方便表述,本章设 ...
- Python数据分析之numpy学习
Python模块中的numpy,这是一个处理数组的强大模块,而该模块也是其他数据分析模块(如pandas和scipy)的核心. 接下面将从这5个方面来介绍numpy模块的内容: 1)数组的创建 2)有 ...
随机推荐
- python面向过程编程 - ATM
前面程序整合加自定义日志 1.文件摆放 ├── xxxx │ ├── src.py │ └── fil_mode.py │ └── data_time.py │ └── loading.py │ └─ ...
- Flume框架的学习使用
Flume框架的学习使用 Flume简介 Flume提供一个分布式的,可靠的,对大数据量的日志进行高效收集.聚集.移动的服务. Flume基于流失架构,容错性强,也很灵活简单 Flume,kafka用 ...
- Java IO部分面试题
1.什么是比特(Bit),什么是字节(Byte),什么是字符(Char),它们长度是多少,各有什么区别 1. Bit最小的二进制单位 ,是计算机的操作部分 取值0或者1 2. Byte是计算机操作数据 ...
- 微信小程序踩坑日记2——实时访问数据库并渲染UI
0. 引言 主要讲讲对于实时访问数据库并渲染UI我的解决方法. 一开始查到了随让小程序是单线程的,但是有一个基本上是封装的worker线程,相当于可以自己自定义(类似于Android开发里的handl ...
- json与js对象间的转化
- 【译】在 Linux 上不安装 Mono 构建 .NET Framework 类库
在这篇文章中,我展示了如何在Linux上构建针对.NET Framework版本的.NET项目,而不使用Mono.通用使用微软新发布的 Mocrosoft.NETFramework.Reference ...
- Reactv16.8.6生命周期函数
组件生命周期函数 React 主动调用的方法,也可重写这些方法 生命周期图谱 当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下: constructor(props) 如果不需要初始化 s ...
- 【iOS】获取应用程序本地路径
Xcode 会为每一个应用程序生成一个私有目录,并随机生成一个数字和字母串作为目录名,在每一次应用程序启动时,这个字母数字串都是不同于上一次. 所以通常使用 Documents 目录进行数据持久化的保 ...
- Lexical or preprocessor 'XXX/XXX.h' issue file not found
最近做第三方登录,引入了第三库,结果就出来个这个问题.如下图所示: 刚开始编译运行都没问题,可下次再打开时就报这个错误…… 一个比较弱智的解决办法: 1. 删除第三方库文件(删除到垃圾箱,而且还要在文 ...
- cookie池的维护
存储形式: 存储在redis中,“spider_name:username–password":cookie 建立py文件及包含方法: initcookies() 初始化所有账号的cooki ...