[Pandas] 02 - Tutorial of NumPy
常见考点
相关参考:NumPy 教程
以下取自于:[Python] 01 - Number and Matrix
一、矩阵 (Matrix)
初始化
mat = np.array([0, 0.5, 1.0, 1.5, 2.0])
mat = np.random.standard_normal((10, 10))
mat = np.zeros((2, 3, 4), dtype='i', order='C')
... 自定义混合类型初始化
统计量
[Pandas] 01 - A guy based on NumPy
Basic Vectorization 向量化
当存在nan元素时,失效;需要排除nan再统计。
矩阵取整
取左地板值
仅保留整数位
四舍五入
矩阵大小
import sys
sys.getsizeof(a)
二、迭代
矩阵下标
index 表示范围
下标表示范围内的“间隔”
矩阵遍历
for x in np.nditer(a, order='F'): Fortran order,即是列序优先;
for x in np.nditer(a.T, order='C'): C order,即是行序优先;
三、形变
扁平化
完全扁平 ravel
自定义扁平 reshape, resize
转置
堆叠
整体对接 vstack, hstack
各取出一个配对 column_stack, row_stack
元素自增加一维度
拆分
四、矩阵拷贝
引用,非拷贝
映射关系 view
深拷贝
五、统计采样
正态分布
其他分布
常见重难点
一、丢失的类型
丢失的数据类型主要有 None 和 np.nan
(1)np.nan是一个float类型的数据;
(2)None是一个NoneType类型。
(a) 在ndarray中显示时 np.nan会显示nan,如果进行计算 结果会显示为NAN
None显示为None 并且对象为object类型,如果进行计算 结果会报错。
所以ndarray中无法对有缺失值的数据进行计算。
(b) 在Serise中显示的时候都会显示为NAN,均可以视作np.nan
进行计算时可以通过np.sum()得到结果,此时NAN默认为0.0
s1 + 10 对于空值得到的结果为NAN,
如果使用加法 可以通过s1.add(参数,fill_value = 0)指定空值的默认值为0
二、副本和视图
ndarray.view() 理解为:共享了“同一片物理地址”,但描述部分,例如维度等是单独的。
ndarray.copy() 理解为:深拷贝。
视图一般发生在:
- 1、numpy 的切片操作返回原数据的视图。
- 2、调用 ndarray 的 view() 函数产生一个视图。
副本一般发生在:
- Python 序列的切片操作,调用deepCopy()函数。
- 调用 ndarray 的 copy() 函数产生一个副本。
三、采样空间
队友:random随机数采样空间。
import numpy as np a = np.linspace(10, 20, 5, endpoint = False)
print(a) # 默认底数是 10
a = np.logspace(1.0, 2.0, num = 10)
print (a)
四、矩阵库(Matrix)
NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
Ref: numpy教程:矩阵matrix及其运算
NumPy函数库中的matrix与MATLAB中matrices等价。
NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能,可以看看下面的说明:
函数 | 描述 |
---|---|
dot |
两个数组的点积,即元素对应相乘。(就是 “矩阵相乘”) |
vdot |
两个向量的点积 |
inner |
两个数组的内积(向量积) |
matmul |
两个数组的矩阵积 |
determinant |
数组的行列式 |
solve |
求解线性矩阵方程 |
inv |
计算矩阵的乘法逆矩阵 |
点积和内积的区别:difference between numpy dot() and inner()
In [103]: a=np.array([[1,2],[3,4]]) In [104]: b=np.array([[11,12],[13,14]]) In [105]: np.dot(a,b) # 矩阵乘法: 1*11+2*13 = 37
Out[105]:
array([[37, 40],
[85, 92]]) In [106]: np.inner(a,b) # 1*11+2*12 = 35, 1*13+2*14 = 41
Out[106]:
array([[35, 41],
[81, 95]])
进一步考察inner:Ordinary inner product of vectors for 1-D arrays (without complex conjugation), in higher dimensions a sum product over the last axes.
In [118]: a=np.array([[1,2],[3,4],[5,6]]) In [119]: b=np.array([[7,8],[9,10],[11,12]]) In [120]: a
Out[120]:
array([[1, 2],
[3, 4],
[5, 6]]) In [121]: b
Out[121]:
array([[ 7, 8],
[ 9, 10],
[11, 12]]) In [122]: np.inner(a,b)
Out[122]:
array([[ 23, 29, 35],
[ 53, 67, 81],
[ 83, 105, 127]])
五、更好的索引
布尔索引
类似于filter。
import numpy as np x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print ('我们的数组是:')
print (x)
print ('\n')
# 现在我们会打印出大于 5 的元素
print ('大于 5 的元素是:')
print (x[x > 5]) # 元素位置被"True/False"置换
print (x > 5)
Output:
我们的数组是:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]] 大于 5 的元素是:
[ 6 7 8 9 10 11] array([[False, False, False],
[False, False, False],
[ True, True, True],
[ True, True, True]])
花式索引
(a) 传入顺序索引数组
import numpy as np
print (x[[4,2,1,7]])
(b) 传入多个索引数组(二级操作,先fiter一次,再filter一次)
import numpy as np x=np.arange(32).reshape((8,4))
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
有点相当于x[[1,5,7,2]][[0,3,1,2]],但不具有顺序性。
实践意义
In [193]: array_3
Out[193]: array([nan, 0., 1., 2., nan]) In [194]: ix = ~np.isnan(array_3) In [195]: array_3[ix]
Out[195]: array([0., 1., 2.]) In [196]: array_3[ix].mean()
Out[196]: 1.0
##########################################
# 作为对比,下面的这个因为nan而无法统计
##########################################
In [197]: array_3.mean()
Out[197]: nan
六、广播机制
计算广播
一般不要用这种“隐式转换”。
import numpy as np a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(a + b)
迭代广播
import numpy as np a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('第一个数组为:')
print (a)
print ('\n')
print ('第二个数组为:')
b = np.array([1, 2, 3, 4], dtype = int)
print (b)
print ('\n')
print ('修改后的数组为:')
for x,y in np.nditer([a,b]):
print ("%d:%d" % (x,y), end=", " )
Output:
第一个数组为:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]] 第二个数组为:
[1 2 3 4] 修改后的数组为:
0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,
七、迭代矩阵
迭代器
默认迭代器选择以更有效的方式对数组进行迭代;当然也可以强制“风格顺序”。
import numpy as np a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\n')
print ('以 C 风格顺序排序:')
for x in np.nditer(a, order = 'C'):
print (x, end=", " )
print ('\n')
print ('以 F 风格顺序排序:')
for x in np.nditer(a, order = 'F'):
print (x, end=", " )
结果:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]] 以 C 风格顺序排序:
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 以 F 风格顺序排序:
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,
可读可写属性
nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only)。
为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。
import numpy as np a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\n')
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('修改后的数组是:')
print (a)
使用外部循环
如果想得到“列的分组”结果,考虑如下方法。
或者考虑ndarrary.flatten(order='F')。
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\n')
print ('修改后的数组是:')
for x in np.nditer(a, flags = ['external_loop'], order = 'C'):
print (x, end=", " )
print()
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print (x, end=", " )
Output:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]] 修改后的数组是:
[ 0 5 10 15 20 25 30 35 40 45 50 55],
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],
降到一维
numpy中的ravel()、flatten()、squeeze()都有将多维数组转换为一维数组的功能,区别:
ravel() | 如果没有必要,不会产生源数据的副本。 |
flatten() | 返回源数据的副本。 |
squeeze() | 只能对维数为1的维度降维。 |
八、字符串操作
以下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作。 它们基于 Python 内置库中的标准字符串函数。
这些函数在字符数组类(numpy.char)中定义。
函数 | 描述 |
---|---|
add() |
对两个数组的逐个字符串元素进行连接 |
multiply() | 返回按元素多重连接后的字符串 |
center() |
居中字符串 |
capitalize() |
将字符串第一个字母转换为大写 |
title() |
将字符串的每个单词的第一个字母转换为大写 |
lower() |
数组元素转换为小写 |
upper() |
数组元素转换为大写 |
split() |
指定分隔符对字符串进行分割,并返回数组列表 |
splitlines() |
返回元素中的行列表,以换行符分割 |
strip() |
移除元素开头或者结尾处的特定字符 |
join() |
通过指定分隔符来连接数组中的元素 |
replace() |
使用新字符串替换字符串中的所有子字符串 |
decode() |
数组元素依次调用str.decode |
encode() |
数组元素依次调用str.encode |
byteswap() |
将 ndarray 中每个元素中的字节进行大小端转换 |
部分生僻难点
数组维度操作。
一、轴对调:numpy.swapaxes
import numpy as np
x = np.array([[[0,1],[2,3]],[[4,5],[6,7]]])
y = np.swapaxes(x,0,2)
print(y)
Output: x轴(0) 和 z轴(2) 调换的结果
[[[0 4]
[2 6]] [[1 5]
[3 7]]]
二、插入轴
一个要点:新添加的轴,必然是shape = 1的。
import numpy as np x = np.array(([1,2],[3,4])) print ('数组 x:')
print (x)
print ('\n')
y = np.expand_dims(x, axis = 0) print ('数组 y:')
print (y)
print ('\n') print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
print ('\n')
# 在位置 1 插入轴
y = np.expand_dims(x, axis = 1) print ('在位置 1 插入轴之后的数组 y:')
print (y)
print ('\n') print ('x.ndim 和 y.ndim:')
print (x.ndim,y.ndim)
print ('\n') print ('x.shape 和 y.shape:')
print (x.shape, y.shape)
输出结果为:
数组 x:
[[1 2]
[3 4]] 数组 y:
[[[1 2]
[3 4]]] 数组 x 和 y 的形状:
(2, 2) (1, 2, 2) 在位置 1 插入轴之后的数组 y:
[[[1 2]] [[3 4]]] x.ndim 和 y.ndim:
2 3 x.shape 和 y.shape:
(2, 2) (2, 1, 2)
三、广播维度 (iter's 笛卡尔积)
x的维度变高后,y的维度通过 “broadcast” 自动升维。
import numpy as np x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6]) # 对 y 广播 x
b = np.broadcast(x,y)
# 它拥有 iterator 属性,基于自身组件的迭代器元组 print ('对 y 广播 x:')
r,c = b.iters # Python3.x 为 next(context) ,Python2.x 为 context.next()
print (next(r), next(c))
print (next(r), next(c))
print (next(r), next(c))
print (next(r), next(c))
print ('\n')
Output:
对 y 广播 x:
1 4
1 5
1 6
2 4
四、正统"笛卡尔积"求解
import itertools class cartesian(object):
def __init__(self):
self._data_list=[] def add_data(self,data=[]): #添加生成笛卡尔积的数据列表
self._data_list.append(data) def build(self): #计算笛卡尔积
for item in itertools.product(*self._data_list):
print(item) if __name__=="__main__":
car = cartesian()
car.add_data([1,2,3])
car.add_data([4,5,6])
car.build()
"相加"过程的broadcast
print ('广播对象的形状:')
print (b.shape)
print ('\n')
b = np.broadcast(x,y)
c = np.empty(b.shape) print ('手动使用 broadcast 将 x 与 y 相加:')
print (c.shape)
print ('\n') # 方案一:手动相加
c.flat = [u + v for (u,v) in b] # <----非常妙!c其实是假降维
print ('调用 flat 函数:')
print (c)
print ('\n')
# 方案二:自动相加;获得了和 NumPy 内建的广播支持相同的结果
print ('x 与 y 的和:')
print (x + y)
Output:
广播对象的形状:
(3, 3) 手动使用 broadcast 将 x 与 y 相加:
(3, 3) 调用 flat 函数:
[[5. 6. 7.]
[6. 7. 8.]
[7. 8. 9.]] x 与 y 的和:
[[5 6 7]
[6 7 8]
[7 8 9]]
broadcast_to之“伪复制”
将数组广播到新形状,有点“复制”的意思;但却是只读,难道是“伪复制”?是的,内存没有增加。
可以使用 sys.getsizeof(<variable>) 获取变量大小。
import numpy as np a = np.arange(4).reshape(1,4) print ('原数组:')
print (a)
print ('\n') print ('调用 broadcast_to 函数之后:')
print (np.broadcast_to(a,(4,4)))
Output:
原数组:
[[0 1 2 3]] 调用 broadcast_to 函数之后:
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
排序算法
根据形式
返回排序结果
按照某个字段排序。
import numpy as np a = np.array([[3,7],[9,1]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 sort() 函数:')
print (np.sort(a))
print ('\n')
print ('按列排序:')
print (np.sort(a, axis = 0))
print ('\n')
# 在 sort 函数中排序字段
dt = np.dtype([('name', 'S10'),('age', int)])
a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)
print ('我们的数组是:')
print (a)
print ('\n')
print ('按 name 排序:')
print (np.sort(a, order = 'name'))
返回排序的索引
返回索引,但可通过x[y]的形式巧妙地得到结果。
import numpy as np x = np.array([3, 1, 2])
print ('我们的数组是:')
print (x)
print ('\n')
print ('对 x 调用 argsort() 函数:')
y = np.argsort(x)
print (y)
print ('\n')
print ('以排序后的顺序重构原数组:')
print (x[y])
print ('\n')
print ('使用循环重构原数组:')
for i in y:
print (x[i], end=" ")
根据多序列排序
每一列代表一个序列,排序时优先照顾靠后的列。
注意,这里一列数据传入的是tuple。
import numpy as np nm = ('raju','anil','ravi','amar')
dv = ('f.y.', 's.y.', 's.y.', 'f.y.')
ind = np.lexsort((dv, nm))
print ('调用 lexsort() 函数:')
print (ind)
print ('\n')
print ('使用这个索引来获取排序后的数据:')
print ([nm[i] + ", " + dv[i] for i in ind])
根据细节
实数、虚数排序
msort(a) | 数组按第一个轴排序,返回排序后的数组副本。np.msort(a) 相等于 np.sort(a, axis=0)。 |
sort_complex(a) | 对复数按照先实部后虚部的顺序进行排序。 |
分区排序
(1) 排序数组索引为 3 的数字,比该数字小的排在该数字前面,比该数字大的排在该数字的后面。
>>> a = np.array([3, 4, 2, 1])
>>> np.partition(a, 3) # 将数组 a 中所有元素(包括重复元素)从小到大排列,3 表示的是排序数组索引为 3 的数字,比该数字小的排在该数字前面,比该数字大的排在该数字的后面
array([2, 1, 3, 4])
>>>
>>> np.partition(a, (1, 3)) # 小于 1 的在前面,大于 3 的在后面,1和3之间的在中间
array([1, 2, 3, 4])
(2) 第 3 小(index=2)的值
>>> arr = np.array([46, 57, 23, 39, 1, 10, 0, 120])
>>> arr[np.argpartition(arr, 2)[2]]
10
(3) 第 2 大(index=-2)的值
>>> arr[np.argpartition(arr, -2)[-2]]
57
(4) 同时找到第 3 和第 4 小的值。
>>> arr[np.argpartition(arr, [2,3])[2]]
10
>>> arr[np.argpartition(arr, [2,3])[3]]
23
(5) numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。
类似布尔索引
numpy.nonzero() 函数返回输入数组中非零元素的索引。
numpy.where() 函数返回输入数组中满足给定条件的元素的索引。
End.
[Pandas] 02 - Tutorial of NumPy的更多相关文章
- HP LoadRunner 12.02 Tutorial T7177-88037教程独家中文版
HP LoadRunner 12.02 Tutorial T7177-88037教程独家中文版 Tylan独家呕血翻译 转载请注明出自“天外归云”的博客园 Welcome to the LoadRun ...
- 使用pandas时遇到ValueError: numpy.dtype has the wrong size, try recompiling
[问题]使用pandas时遇到ValueError: numpy.dtype has the wrong size, try recompiling [原因] 这是因为 Python 包的版本问题,例 ...
- Pandas | 02 Series 系列
系列(Series)是能够保存任何类型的数据(整数,字符串,浮点数,Python对象等)的一维标记数组.轴标签统称为索引. pandas.Series Pandas系列可以使用以下构造函数创建 - p ...
- pandas、matplotlib、Numpy模块的简单学习
目录 一.pandas模块 二.matplotlib模块 1.条形图 2. 直方图 3.折线图 4.散点图+直线图 三.numpy 一.pandas模块 pandas是BSD许可的开源库,为Pytho ...
- 数据可视化实例(三): 散点图(pandas,matplotlib,numpy)
关联 (Correlation) 关联图表用于可视化2个或更多变量之间的关系. 也就是说,一个变量如何相对于另一个变化. 散点图(Scatter plot) 散点图是用于研究两个变量之间关系的经典的和 ...
- [AI] 深度数据 - Data
Data Engineering Data Pipeline Outline [DE] How to learn Big Data[了解大数据] [DE] Pipeline for Data Eng ...
- Numpy and Pandas
安装 视频链接:https://morvanzhou.github.io/tutorials/data-manipulation/np-pd/ pip install numpy pip instal ...
- pandas tutorial 2
@ 目录 Group_By 对数据进行分组 对 group进行迭代 选择一个group get_group() Aggregations 在group的基础上传入函数整合 Transformation ...
- 数据分析之Pandas和Numpy学习笔记(持续更新)<1>
pandas and numpy notebook 最近工作交接,整理电脑资料时看到了之前的基于Jupyter学习数据分析相关模块学习笔记.想着拿出来分享一下,可是Jupyter导出来h ...
随机推荐
- Linux相关安装文档
一.JDK环境安装 1.查看linux上是否存在已安装好的JDK (1)java -version openjdk version "1.8.0_181"OpenJDK Runti ...
- Ubuntu 18.04 下载地址
http://mirrors.163.com/ubuntu-releases/18.04/
- 【MySQL】索引
什么是索引 索引就好比是书的目录,可以显著提高数据库查询的效率.例如像一本很厚的书,在没有目录的情况下要查到你想要看的知识点,都不知要找到什么时候,但通过目录我们可以很快的查询到对应的内容. 索引的数 ...
- js获取Cookie,获取url参数
function getCookie(name) { var strCookie = document.cookie; var arrCookie = strCookie.split("; ...
- linux的一些简单命令
简单学习了一些linux相关的知识,自己做一个简单的总结,可以在一般工作中命令行状态下装装B,哈哈 正则相关 grep grep xxx yyy.file 查找出yyy文件中存在xxx的行 通配符 * ...
- centos7搭建hadoop3.*.*系列
最近搭建这个hadoop踩过不少坑,先是配置JDK搞错路径(普通用户和root用户下的路径不同),再就是hadoop版本不同导致的启动错误,网上找到的是hadoop2.*.*的版本,但是我安装的had ...
- 2. Sentinel源码分析—Sentinel是如何进行流量统计的?
这一篇我还是继续上一篇没有讲完的内容,先上一个例子: private static final int threadCount = 100; public static void main(Strin ...
- HTTP 8中请求方式介绍
HTTP请求方式中8种请求方法(简单介绍) 简单介绍 HTTP是超文本传输协议,其定义了客户端与服务器端之间文本传输的规范.HTTP默认使用80端口,这个端口指的是服务端的端口,而客户端使用的端口 ...
- POJ - 3436 ACM Computer Factory 网络流
POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...
- 牛客19985 HAOI2011向量(裴属定理,gcd)
https://ac.nowcoder.com/acm/problem/19985 看到标签“裴属定理”就来做下,很眼熟,好像小学奥数学过.. 题意:给你a,b,x,y,你可以任意使用(a,b), ( ...