文章数据
收藏(次)
【python数据分析】第四章 NumPy基础-2
NumPy数组的运算:
数组很重要,因为它使你不用编写循环即可对数据执行批量运算。NumPy用户称其
为矢量化(vectorization)。大小相等的数组之间的任何算术运算都会将运算应用
到元素级
相同大小的数组:矢量和矢量的运算:加 减 乘 除, 比较, 传播到每个元素
不相同大小的数组:不同大小的数组之间的运算叫做广播 不讨论
矢量和标量的运行:加 减 乘 除,幂... 传播到每个元素
--------------------------------------------------------------------------------
a = [1,2,3]
# py内建的数组,报错,无法传播到内部的元素中 TypeError: can only assign an iterable
a[1:2] = 10
numpy的操作不复制数据,由于NumPy的设计目的是处理大数据,所以你可以想象一下,
假如NumPy坚持要将数据复制来复制去的话会产生何等的性能和内存问题。
--------------------------------------------------------------------------------
numpy数组的 索引和切片:
arr[1] # 索引
arr[1:3] # 切片
arr[1:3] = 100 # 传播 [1-3) 元素改变, 如果是 python数组,报错了
切片没有创建新的数组,而是一个索引
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import numpy as np
arr = np.array([0,1,2,3,4,5,6,7])
arr[1:3] = 100
print(arr) # [ 0 100 100 3 4 5 6 7]
arr_s = arr[3:5] # 没有产生新的数组
arr_s[0] = 999
print(arr) # 原数据 arr 不变,输出 [ 0 100 100 999 4 5 6 7]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
二维的两种索引:
arr2d[2,1]
arr2d[2][1]
def do_fun():
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2d[2], arr2d[2,1], arr2d[2][1]) #[7 8 9] 8 8
arr2d[0] = 100 # 传播,第一行的三个元素全部赋值成 100
print(arr2d)
--------------------------------------------------------------------------------
切片:
一维数组切片和 py 内建数组差不多,但是 np 切片返回的是视图,原数组的部分引用,
多维数组切片
def do_fun():
arr2d = np.array([[1, 2, 3, 4,5], [4, 5, 6,7,8], [7, 8, 9, 10, 11]])
d1 = arr2d[0:2, 1:3]
d2 = arr2d[0:2][1:3]
print(d1)
print(d2)
输出:
[[2 3]
[5 6]]
[[4 5 6 7 8]]
d1 和 d2 的写法不在等价了。 d1 是两次切片同时应用到数组上,得到一个块
d2 是两次切片,有先后,先切了 0:2 得到原数组的 [[1, 2, 3, 4,5], [4, 5, 6,7,8]]
然后再在结果上切[1:3] 现在结果只有两个,切1:3 得到 [4, 5, 6,7,8]]
d1 是先行,列上都做号切割位置,切一次
d2 是先切行,然后再在结果上再次切行
--------------------------------------------------------------------------------
bool 索引:
比如,有一个二维数组,现在只想要奇数行的数据,可以切片,也可以使用 bool 索引:
data = np.random.randn(7, 4)
data
输出:
array([[ 0.92054306, -1.14720675, -0.27059536, -0.20354474],
[ 0.51584825, -0.98949536, 1.09868627, -0.73546964],
[ 0.34284003, 0.216976 , -0.05913678, -0.70254513],
[ 1.00694513, 0.63887281, 1.13132181, -0.27362559],
[-1.14401903, -0.79587189, -0.93498817, 0.42576963],
[ 0.90200621, 0.41463213, 0.01800469, -1.64614623],
[-0.58754865, 0.72193939, -0.72912538, 0.89489043]])
只要奇数行,一共7行, 保留行的使用 True, 不要的使用 False
idx = [True, False, True, False, True, False, True] # 设置哪些想要的
data[idx] # 索引出来,
输出:
array([[ 0.92054306, -1.14720675, -0.27059536, -0.20354474],
[ 0.34284003, 0.216976 , -0.05913678, -0.70254513],
[-1.14401903, -0.79587189, -0.93498817, 0.42576963],
[-0.58754865, 0.72193939, -0.72912538, 0.89489043]])
作用:比如把小于0的变成0
data[data < 0] = 0
data
输出:
array([[0.92054306, 0. , 0. , 0. ],
[0.51584825, 0. , 1.09868627, 0. ],
[0.34284003, 0.216976 , 0. , 0. ],
[1.00694513, 0.63887281, 1.13132181, 0. ],
[0. , 0. , 0. , 0.42576963],
[0.90200621, 0.41463213, 0.01800469, 0. ],
[0. , 0.72193939, 0. , 0.89489043]])
data < 0 得到一个true false 组成的同型二维数组,
data[true,fase 的数组] = 0 为 True 的应用这个操作。
d2 = data[data > 0.1]
d2
输出:
array([0.92054306, 0.51584825, 1.09868627, 0.34284003, 0.216976 ,
1.00694513, 0.63887281, 1.13132181, 0.42576963, 0.90200621,
0.41463213, 0.72193939, 0.89489043])
可以看到 d2 变成了一个一维数组,都是满足要求的元素组成的
data[这里只能是标量整数或者 bool组成的数组类型], 否则报错如下:
IndexError: arrays used as indices must be of integer (or boolean) type
整数它理解成索引,bool类型数组它理解成花式索引
中间的条件还能引用 ~ & | 等位运算符号
--------------------------------------------------------------------------------
花式索引:
花式索引可能改变了原数组的位置,所以花式索引一直是copy数据形成新的数组,不同于切片
arr = np.empty((8, 4))
for i in range(8):
arr[i] = i
arr
输出:
array([[0., 0., 0., 0.],
[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.],
[4., 4., 4., 4.],
[5., 5., 5., 5.],
[6., 6., 6., 6.],
[7., 7., 7., 7.]])
arr[[5,2,1]] # 现在想要 第5,2,1,按照这个顺序,改变源数据顺序,产生新的数组,有数据copy
输出:
array([[5., 5., 5., 5.],
[2., 2., 2., 2.],
[1., 1., 1., 1.]])
arr[[-5,-2,-1]]
输出:
array([[3., 3., 3., 3.],
[6., 6., 6., 6.],
[7., 7., 7., 7.]])
如果索引是多个数组,就特别了:
arr = np.arange(32).reshape(8, 4)
arr
输出:
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]])
arr[[1,3], [2,1]] # 原以为,先要索引是1和3的行, 然后再 这两行中索引是2和1的列,也就 2*2的新数组
输出:
array([ 6, 13]) #实际上 输出为啥是1维数组,相当于 取了原数组的 1,2 3,1 的数据
如果想要上面说的 2*2 的数组怎么办
arr[[1,3]][:, [2,1]]
输出:
array([[ 6, 5],
[14, 13]])
================================================================================
数组的转置
--------------------------------------------------------------------------------
arr = np.arange(32).reshape(8, 4)
arr
输出:
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]])
arr.T
输出:
array([[ 0, 4, 8, 12, 16, 20, 24, 28],
[ 1, 5, 9, 13, 17, 21, 25, 29],
[ 2, 6, 10, 14, 18, 22, 26, 30],
[ 3, 7, 11, 15, 19, 23, 27, 31]])
二维数组直接转置就是轴转换,但是三维数组轴转换就使用方法实现,需要指定 哪个轴(搞不明白了)
arr.transpose((1, 0, 2))
arr.swapaxes(1, 2) # 也是三维,轴兑换
--------------------------------------------------------------------------------
分享
收藏
点赞人
举报
文章标签
评论列表