numpy 初识
一个简单的List
data_1 = [[1,2,3,4],[5,6,7,8]]
print(data_1)
print(type(data_1))
输出为:
[[1, 2, 3, 4], [5, 6, 7, 8]]
<class 'list'>
# NumPy最重要的一个特点就是其N维数组 对象(即ndarray),可以利用这种数组对整块 数据执行一些数学运算,其语法跟标量元素之 间的运算一样
import numpy as np
data = [[1,2,3,4],[5,6,7,8]]
data = np.array(data)
print(data.dtype)
print(data+data)
print(data*10)
print(data.shape)
输出为:
int32
[[ 2 4 6 8]
[10 12 14 16]]
(2, 4)
说明:
ndarray是一个通用的同构数据多维容器, 也就是说,其中的所有元素必须是相同类型 的。每个数组都有一个shape(一个表示各维度 大小的元组)和一个dtype(一个用于说明数组 数据类型的对象):
#创建ndarray
data = [1,2.5,3,6]
arr_data = np.array(data)
print(arr_data)

#zeros和ones分别可以创建指定 长度或形状的全0或全1数组
data_zeros = np.zeros(10)
data_ones = np.ones(10)
print(data_zeros)
print(data_ones)

data = np.zeros((2,3))
print(data)

#arange是Python内置函数range的数组版
np.arange(10)
[0 1 2 3 4 5 6 7 8 9]
#下表列出了一些数组创建函数由于NumPy关注的是数值计算,因此,如果没有特 别指定,数据类型基本都是float64(浮点 数)

data = np.ones((3,5))
print(data.dtype)

#ndarray的数据类型
dtype(数据类型)是一个特殊的对象,它 含有ndarray将一块内存解释为特定数据类型所 需的信息


data_2 = np.array(l,dtype=np.float64)
print(data_2.dtype)
# 输出为 float64
#你可以通过ndarray的astype方法显式地转 换其dtype
list = [1,2,3,4,5]
data = np.array(list)
print(data.dtype)
data = data.astype("float64")
print(data.dtype)

在上面例子中,整数被转换成了浮点数。但是,如果将浮点数转换成整数,则小数部分将会被截断
#如果某字符串数组表示的全是数字,也可 以用astype将其转换为数值形式
list = ['1','2','3.0','4.0','5']
data = np.array(list)
print(data.dtype)
data = data.astype("float")
print(data.dtype)
# 输出
<U3
float64
如果转换过程因为某种原因而失败了(比 如某个不能被转换为float64的字符串),就会 引发一个TypeError。看到了吧,我比较懒,写 的是float而不是np.float64;NumPy很聪明, 它会将Python类型映射到等价的dtype上。
数组的dtype还有另外一个用法
list_1 = ['1','2','3.0','4.0','5']
data = np.array(list_1)
l_2 = np.arange(10)
data_2 = l_2.astype(data.dtype)
print(data_2.dtype)
输出为:
<U3
#数组和标量之间的运算
数组很重要,因为它使你不用编写循环即 可对数据执行批量运算。这通常就叫做矢量化 (vectorization)。大小相等的数组之间的任 何算术运算都会将运算应用到元素级
list_1 = [[1,2,3,4],[5,6,7,8]]
array_list = np.array(list_1)
print(array_list+array_list)
print(array_list*array_list)
同样,数组与标量的算术运算也会将那个 标量值传播到各个元素
print(array_list**2)
#基本的索引和切片
NumPy数组的索引是一个内容丰富的主 题,因为选取数据子集或单个元素的方式有很 多。一维数组很简单。从表面上看,它们跟 Python列表的功能差不多
data = np.arange(10)
print(data[1:6])
# 输出 [1 2 3 4 5]
当你将一个标量值赋值给一个 切片时(如arr[5:8]=12),该值会自动传播 (也就说后面将会讲到的“广播”)到整个选 区。跟列表最重要的区别在于,数组切片是原 始数组的视图。这意味着数据不会被复制,视 图上的任何修改都会直接反映到源数组上
data[1:6]=9
print(data)
#输出 [0 9 9 9 9 9 6 7 8 9]
但是,一个列表切片赋单一值的话,会报错
l_list = [1,2,3,4,5]
l_list[0:3]=9
print(l_list)

如果你刚开始接触NumPy,可能会对此感 到惊讶(尤其是当你曾经用过其他热衷于复制 数组数据的编程语言)。由于NumPy的设计目 的是处理大数据,所以你可以想象一下,假如 NumPy坚持要将数据复制来复制去的话会产生 何等的性能和内存问题。
警告: 如果你想要得到的是ndarray切片 的一份副本而非视图,就需要显式地进行复制 操作,例如arr[5:8].copy()。
对于高维度数组,能做的事情更多。在一 个二维数组中,各索引位置上的元素不再是标 量而是一维数组
data = np.array([[1,2,3],[4,5,6],[7,8,9,10]])
print(data[1])
输出[4,5,6]
你可以传入一个以 逗号隔开的索引列表来选取单个元素。下面两种方式是等价的
data[0][2]
data[0,2]
标量值和数组都可以赋值给数组,
data = np.arange(24).reshape(2,3,4)
print(data)
new_data = data[1].copy()
data[1] = 42
print(data)
data[1] = new_data
print(data)

高维度对象的花样更多,你可以在一个或 多个轴上进行切片,也可以跟整数索引混合使 用
沿着一个轴切片,即也就是说,切片是沿着一个轴向选取 元素的。你可以一次传入多个切片,就像传入 多个索引那样
data = np.arange(24).reshape(6,4)
print(data[0:3])
print(data[0:3,0:3]
输出为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[ 0 1 2]
[ 4 5 6]
[ 8 9 10]]
通过将整数索引和切片混合,可以 得到低维度的切片
print(data[1,0:2])
输出 :[8 9]
“只有冒 号时”表示选取整个轴
data[:,1:3]
布尔型索引
list = ["bob","jack", 'Joe', 'Will', 'bob', 'Will']
names = np.array(list)
我们想要选出对应于名字"Bob"的所有行。跟 算术运算一样,数组的比较运算(如==)也是 矢量化的
print(names == "bob")
输出为 [ True False False False True False]
data = np.random.randn(6,4)
print(data[names == "bob"])

注意:布尔型数组的长度必须跟被索引的轴长度 一致。此外,还可以将布尔型数组跟切片、整 数(或整数序列,稍后将对此进行详细讲解) 混合使用
data[names == 'Bob', 2:]
要选择除"Bob"以外的其他值,既可以使用 不等于符号(!=),也可以通过负号(-)对 条件进行否定
data[names != 'bob']
选取这三个名字中的两个需要组合应用多 个布尔条件,使用&(和)、|(或)之类的布 尔算术运算符即可
警告: Python关键字and和or在布尔型数 组中无效。
花式索引
花式索引(Fancy indexing)是一个 NumPy术语,它指的是利用整数数组进行索 引
为了以特定顺序选取行子集,只需传入一 个用于指定顺序的整数列表或ndarray即可
data = np.random.rand(7,4)
for i in range(7):
data[i] = i
print(data)
print(data[[1,3,5]]) #[1,3,5] []里面的1,3,5表示的时索引
[[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.]]
[[1. 1. 1. 1.]
[3. 3. 3. 3.]
[5. 5. 5. 5.]] # 这里的输出值为1,3,5列表
这段代码确实达到我们的要求了!使用负 数索引将会从末尾开始选取行
data[[-1,-3,-5]]
print(data[[1,3,5],[0,2,3]]) # [1. 3. 5.]
注意:这里data[[1,3,5],[0,2]]会报错,因为第5行没有值和它对应了,必须要位数一样。
最终选出 的是元素(1,0)、(5,3)、(7,1)和(2,2)
数组转置和轴对换
转置(transpose)是重塑的一种特殊形 式,它返回的是源数据的视图(不会进行任何 复制操作)。数组不仅有transpose方法,还有 一个特殊的T属性
arr = np.arange(15).reshape((3, 5))
array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
arr.T
输出为:
array([[ 0, 5, 10], [ 1, 6, 11], [ 2, 7, 12], [ 3, 8, 13], [ 4, 9, 14]])
通用函数:快速的元素级数组函数
通用函数(即ufunc)是一种对ndarray中 的数据执行元素级运算的函数。你可以将其看 做简单函数(接受一个或多个标量值,并产生 一个或多个标量值)的矢量化包装器
data = np.arange(12).reshape((3,4))
print(data)
print(np.sqrt(data)) #开方
np.maximum(x, y) # 元素级最大值
data = np.arange(12).reshape((3,4))
print(data)
data_2 = np.random.rand(12).reshape((3,4))
print(data_2)
print(np.maximum(data,data_2))
输出为:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[0.93580781 0.31785134 0.62023201 0.05954647]
[0.67454843 0.63632348 0.05396736 0.52836042]
[0.77522635 0.53302003 0.9306724 0.73201755]]
[[ 0.93580781 1. 2. 3. ]
[ 4. 5. 6. 7. ]
[ 8. 9. 10. 11. ]]

浙公网安备 33010602011771号