numpy使用


numpy入门

1.1 理解python中的数据类型

1.1.1 python中的列表

l = list(range(10))
print(l)
l2 = [str(c) for c in l]
l3 = [True, "2", 3.0, 4]
l4 = [type(item) for item in l3]

1.1.2 python中固定类型的数组

import array
l = list(range(10))
a = array.array('i', l)
print(a)

1.1.3 从python列表创建数组

import numpy as np
a = np.array([1, 4, 5, 3])
#如果希望明确的设置数据类型 可以使用dtype关键字
b = np.array([1, 2, 3, 4], dtype='float32')
# 嵌套列表构成的多维数组
c = np.array([[2, 3, 4], [4, 5, 6], [6, 7, 8]])

1.1.4 从头创建数组

a = np.zero(10, dtype=int) #长度为10的数组,数组的值都是0
b = np.ones((3, 5), dtype=float)
c = np.full((3, 5), 3.14) 
d = np.arange(0, 20, 2) #数组的值是线性序列,从0开始到20 结束,步长为2
e = np.linspace(0, 1, 5) #创建一个5个元素的数组,这5个数均匀分布到0~1
f = np.random.random((3, 3)) #创建一个3 * 3在0~1之间均匀分布的数组
g = np.random.normal(0, 1, (3, 3)) #创建一个3*3,均值为0,方差为1的正态分布的随机数数组
h = np.random.randint(0, 10, (3, 3)) #创建一个3 * 3的【0,10)区间的随机整数数组
i = np.eye(3) #创建一个3*3的单位矩阵
j = np.empty(3) # 创建一个由三个整形数组组成的未初始化的数组数组的值是内存空间中的任意值

1.2 numpy数组基础

1.2.1 numpy数组的属性

import numpy as np
np.random.seed(0)
x1 = np.random.randint(10, size=6)
x2 = np.random.randint(10, size=(3, 4))
x3 = np.random.randint(10, size=(3, 4, 5))
print(x3.ndim) #数组的维度
print(x3.shape) #每个维度的大小
print(x3.size) #数组的总大小
print(x3.dtype) #数组的数据类型
print(x3.itemsize) #每个数组元素字节大小
print(x3.nbytes) #数组总字节大小
#nbytes = itemsize * size

1.2.2 数组索引获取单个元素

x1 = np.array([1, 2, 3, 4])
print(x1[0])
# 为了获取数组的末尾索引可以用负值索引
print(x1[-1])
print(x1[-2])
#在多维数组中,可以使用逗号分隔的索引元组获取元素
x2 = np.random.randint(12, size(3, 4))
print(x2[0, 0])
#也可以通过索引的方式修改元素值
x2[0,0] = 12
#请注意和python列表不同,numpy的数组是固定类型的,如果将一个浮点数类型的数据插入一个整形数组时,浮点值会被截断为整形

1.2.3 数组切片:获取子数组

#一维子数组
x = np.arange(10)
x[:5] #前5个元素
x[5:] #后五个元素
x[::2] #每隔一个元素
x[::-1] #所有元素,逆序
#多维子数组
x2 = np.random.randint(12, size=(3, 4))
print(x2[:2, :3]) #两行三列
x2[:3, ::2] #所有行每隔一列
#子数组维度也可以同时被逆序
x2[::-1, ::-1]
#获取数组的行和列
print(x2[:, 0]) #x2的第一列
print(x2[0, :]) #x2的第一行
#获取行时,处于语法的简介考虑,可以省略空的切片
print(x2[0]) #等价于 x2[0, :]
#非副本视图的子数组
#数组切片返回的是数组数据的视图,而不是数值数据的副本
x2_sub = x2[:2, :2]
print(x2_sub)
#如果修改这个子数组,则原数组也会被修改
x2_sub[0, 0] = 99
print(x2)

#创建数组的副本
x2_sub_copy = x2[:2, :2].copy()
#修改这个子数组原始的数组不会发生改变

1.2.4 数组的变形

grid = np.arange(1, 10).reshape((3, 3))
print(grid)
x = np.array([1, 2, 3])
#通过变形获取行向量
x.reshape((1,3))
#通过newaxis获取行向量
x[np.newaxis, :]
#通过变形获取列向量
x.reshape((3, 1))
#通过newaxis获取列向量
x[:, np.newaxis]

1.2.5 数组拼接和分裂

x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
np.concatenate([x, y])
z = [99, 99, 99]
print(np.concatenate[x, y, z])
grid = np.array([[1, 2, 3], [4, 5, 6]])
np.concatenate([grid, grid]) #默认按列进行拼接
np.concatenate([grid, grid], axis=1) #按行进行拼接

#沿着固定维度处理数组的时候,np.vstack() np.hstack()更简洁
np.vstack([x, grid])
y = np.arraty([[99], [99]])
np.hstack([grid, y])


#数组的分裂
x = [1, 2, 3, 4 ,5, 6, 9, 0, 9]
x1, x2, x3 = np.split(x, [3, 5])
print(x1, x2, x3)
grid = np.arange(16).reshape((4, 4))
upper, lower = np.vsplit(grid, [2])
left, right = np.hsplit(grid, [2])

1.3 numpy 数组的计算:通用函数

1.3.1 探索numpy的通用函数

x = np.arange(4)
print(x + 5)
print(x / 2)
np.add(x, 2)
print(np.subtract(x, 2))
print(x)
x = np.array([-2, -1, 0, 1, 2])
print(abs(x))
theta = np.linspace(0, np.pi, 3)
print(sin(theta))

x = [1, 2, 4, 10]
print(exp(x) - 1)
print(log(1 + x))

1.3.2高级的通用函数特性

x = np.arange(5)
y = np.empty(5)
np.multiply(x, 10, out=y)
print(y)

y = np.zeros(10)
np.power(2, x, out=y[::2])
print(y)

#聚合
#对add通用函数调用reduce方法会返回数组中所有元素的和
x = np.arange(1, 6)
np.add.reduce(x)
#对multiply调用reduce方法会返回所有元素的乘积
np.multiply.reduce(x)
#如果需要存储每次计算的中间结果,可以使用accumulate
np.add.accumulate(x)
#外积
#任何通用函数都可以用outer方法获取两个不同输入数组的所有元素对的函数运算结果
x = np.arange(1, 6)
np.multiply.outer(x, x)

1.4 聚合:最小值,最大值和其他值

1.4.1 数组值求和

import numpy as np
l = np.random.random(100)
sum(l)
np.sum(l)

1.4.2 最大值和最小值

a = np.min(l)
b = np.max(l)
#多维度聚合
M = np.random.random((3, 4))
M.sum()
M.min(axis=0) #求出每一列的最小值
M.min(axis=1) #求出每一行的最小值

1.5 数组的计算:广播

1.5.1广播的介绍

a = np.array([1, 2, 3])
b = np.array([5, 5, 5])
c = a + b
d = a + 5
M = np.ones((3, 3))
e = M + a
#复杂的广播示例
a = np.arange(3)
b = np.arange(3)[:, np.newaxis]
print(a)
print(b)
print( a + b)

1.5.2 广播的规则

  • 规则1:如果两个数组的维度数不相同,那么小维度数组的形状将会在最左边补1
  • 规则2:如果两个数组的形状在任何一个维度上都不匹配,那么数组的形状会沿着维度为1的维度扩展一匹配另一个数组的形状
  • 规则3:如果两个数组的形状在任何一个维度上都不匹配并且没有任何一个维度等于1,那么会引发异常
M = np.ones((2, 3))
a = np.arange(3)
print(M + a)

a = np.arange(3).reshape((3, 1))
b = np.arange(3)
print(a + b)

M = np.ones((3, 2))
a = np.arange(3) 
print(M + a) #这两个数组是不兼容的,无法进行相加

1.5.3 广播的实际应用

#数组的归一化
x = np.random.random((10, 3))
x_mean = x.mean(0)
x_centered  = x - x_mean
x_centered.mean(0) #检查归一化的数组的均值是否接近0
#画一个二维数组
x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 50)[:, np.newaxis]
z = np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
import matplotlib.pyplot as plt
plt.imshow(z, origin='lower', extent=[0, 5, 0, 5], cmap='viridis')
plt.colorbar();

1.6 比较,掩码,和布尔逻辑

1.6.1 和通用函数类似的比较操作

x = np.array([1, 2, 3, 4, 5])
print(x < 4)
#np.equal==  np.not_equal !=   np.less <  np.greater >

1.6.2 操作布尔数组

  • 如果需要统计布尔数组中True记录的个数,可以使用np.count_nonzero函数
np.count_nonzero(x < 6)
np.sum(x < 6) 
np.sum(x < 6, axis = 1) #每行有多少值小于6

#有没有值大于8
np.any(x > 8)
#是否所有的值都大于8
np.all(x > 8)
#np.all(), np.any() 也可以沿着特定的坐标轴


#布尔运算
np.sum((inches > 0.5) & (inches < 1))

1.6.3 将布尔数组当做掩码

x = np.arange(12).reshape((3, 4))
x[x < 5] #选出值小于5的数

1.7 花哨的索引

1.7.1 探索花哨的索引

import numpy as np
rand = np.random.RandomState(42)
x = np.random.randint(100, size=10)
print(x)
print(x[3], x[7], x[2])
ind = [3, 7, 2]
print(x[ind])
#利用索引其结果的形状与索引数组的形状一致,而不是与被索引数组的形状一致
y = np.arange(12).reshape((3, 4))
row = np.array([0, 1, 2])
col = np.array([2, 1, 3])
print(y[row, col])
print(y[row:, np.newaxis], col)
print(row[:, np.newaxis] * col)

1.7.2 组合索引

x = np.random.randint(12, size=(3, 4))
print(x[2, [2, 0, 1]])
print(x[1:, [2, 0, 1]])
mask = np.array([1, 0, 1, 0], dtype=bool)
print(x[row:, np.newaxis], mask)

1.7.3 利用花哨的索引修改值

x = np.arange(10)
i = np.arraty([2, 1, 8, 4])
x[i] = 99
print(x)

i = [2, 3, 3, 4, 4, 4]
x[i] += 1
print(x)

x = np.zero(10)
np.add.at(x, i, 1)
print(x)

1.8 数组的排序

#简单的选择排序
import numpy as np
def selection_sort(x):
    for i in range(len(X)):
        swap = i +np.argmin(x[i:])
        (x[i], x[swap]) = (x[swap], x[i])
    return x
x = np.array([2, 1, 4, 3, 5])
x = selection(x)
print(x)

1.8.1Numpy中的快速排序,np.sort和np.argsort

x = np.array([2, 1, 4, 3, 5])
np.sort(x)
#argsort函数返回的原始数组排好序的索引值
x = np.array([3, 1, 9])
i = np.argsort(x)
print(i)

#沿着行或列进行排序
rand = np.random.Randomstate(42)
x = random.randint(0, 10, (4, 6))
print(x)
np.sort(x, axis=0) #对x的每一列进行排序
np.sort(x, axis=1) #对x的每一行进行排序

1.8.2 部分排序:分割

x = np.array([1, 3, 5, 9, 3, 8])
np.partition(x, 3)
#np.partition函数的输入是数组和数字的k,输出结果是一个新的数组,最左边是第k小的值,往右是任意顺序的其他值
#也可以沿着多维数组任意的轴进行分隔
np.partition(x, 2, axis = 1)

1.9 结构化数据:numpy的结构化数组

1.9.1 生成结构化数组

name = ['alice', 'bob', 'cathy', 'doug']
age = [25, 45, 37, 19]
weight = [55.0, 85.5, 68.0, 61.5]
x = np.zeros(4, dtype=int)
#通过制定符合数据类型,可以构造一个结构化数组
data = no.zeros(4, dtype={'name':('name', 'age', 'weight'), 'formats':('U10', 'i4', 'f8')})
print(data.dtype)
data['name'] = name
data['age'] = age
data['weight'] = weight
print(data['name'])
print(data[0])
#获取年龄小于30岁的人的名字
data[data['age'] < 30]['name']

1.9.2 更高级的复合类型

#你可以创建一种类型,其中每个元素都包含一个数组或矩阵,我们将创建一个数据类型,该数据类型用mat组件包含一个3*3的浮点矩阵
tp = np.dtype([('id', 'i8'), ('mat', 'f8', (3, 3))])
x = np.zeros(1, dtype=tp)
print(x[0])
print(x['mat'][0])

1.9.3 记录数组:结构化数组的扭转

name = ['alice', 'bob', 'cathy', 'doug']
age = [25, 45, 37, 19]
weight = [55.0, 85.5, 68.0, 61.5]
x = np.zeros(4, dtype=int)
#通过制定符合数据类型,可以构造一个结构化数组
data = no.zeros(4, dtype={'name':('name', 'age', 'weight'), 'formats':('U10', 'i4', 'f8')})
print(data.dtype)
data['name'] = name
data['age'] = age
data['weight'] = weight

data_rec = data.view(np.recarry)
data_rec.age

相关