python进阶—numpy教程

简介

        numpy作为作为python中科学计算的核心库,包含了很多实用的数学函数,涵盖线性代数运算、傅里叶变换、随机数生成等功能。它提供了一个高性能多维数据对象,以及操作这个对象的工具。

       1、多维数组创建(ndarray)

import numpy as np

# 数组的创建(ndarray)
print("####数组的创建####")
a1 = np.array([1, 2, 3])
a2 = np.array([[1, 2, 3], [4, 5, 6]])
a3 = np.array([range(5), range(5)])
a4 = np.array((1, 2, 3))
b1 = np.arange(10).reshape(2, 5)
b2 = np.arange(24).reshape(2, 3, 4)
b3 = np.arange(0, 10, 2)  # 设置步长为2的数组

# 特殊数组的创建
print("####特殊数组的创建####")
c1 = np.zeros((3, 4))  # 零矩阵
c2 = np.zeros((3, 4), dtype="int32")
c3 = np.ones((3, 4))  # 元素全为1
c4 = np.ones((3, 4), dtype="int32")
c5 = np.eye(4, dtype="int32")  # 对角线元素全为1
c6 = np.linspace(0, 10, 6)  # 等差数组,总长度为6
c7 = np.repeat([1, 2, 3], 3)  # 重复元素[1,2,3]三次
c8 = np.full((2, 3), 7)  # 2行3列,元素全为7
c9 = np.random.random([3, 4])  # 随机数组3行4列
c10= np.tile(a1,(2,2))  # [[1,2,3,1,2,3] [1,2,3,1,2,3]]

        numpy的主要对象是同种元素的多维数组,这是一个所有元素类型一样的元素表格,numpy的数组类型被称为ndarray.

        2、多维数组的属性

# 数组的属性
d = np.arange(24).reshape(2, 3, 4)
array_rank = d.ndim  # 数组的秩 3 (轴的个数,即d中元素需要几个下标表示)
array_shape = d.shape  # 数组的维度 (2,3,4)
array_size = d.size  # 数组中元素的总个数 24
array_dtype = d.dtype  # 数组中元素的类型 int32
array_itemsize = d.itemsize  # 每个元素的字节大小 4
array_flat = d.flat  # 扁平迭代器(Iterable)

         3、多维数组的方法

# 通用函数(axis=0:跨行计算,axis=1跨列计算)
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[6, 5, 4], [3, 2, 1]])
array1 = np.array([1,2,3,4,5])
np.sum(a, axis=0)  # a.sum(axis=0)#求和
np.cumsum(a, axis=0)  # 累计跨行求和
np.cumprob(a,axis=0)  # 累计跨行求积
np.prod(array1)  # 计算阶乘
np.cumprod(array1)  # 计算累计阶乘
np.sin(a), np.sqrt(a), np.log(a), np.sum(a), np.min(a), np.max(a), np.mean(a), np.std(a)

        4、多维数组索引和切片

a = np.array([[1, 2, 3], [4, 5, 6]])
# 扁平迭代器
a.flat[0][0]
# 索引
index_a1 = a[0][0]
index_a2 = a[0]
bool_a1 = a[a>1]
# 切片
slice_array1 = a[0:1, 0:1]  # 获取第1行第1列元素
slice_array2 = a[0:, 0:1]  # 获取第1行到最后一行,第1列的所有元素
slice_array3 = a[..., 0:1]  # 获取所有行的第一列元素
slice_array4 = a[::-1]  # 获取所有行所有列,行反转

        5、多维数组的迭代

a = np.array([[1, 2, 3], [4, 5, 6]])
# 按行遍历数组
for row in a:
    print(row) #[1,2,3] [4,5,6]
# 遍历数组中的每个元素
for ele in np.nditer(a):
    print(ele) #1,2,3,4,5,6
# 遍历数组中的每个元素
for ele in a.flat:
    print(ele) #1,2,3,4,5,6

       6、更改数组的形状和类型

# 更改数组的形状
a = np.array([[1, 2, 3], [4, 5, 6]])
# 扁平迭代器
descent_a1 = a.flatten()  # 将多维数组变成一维数组,修改一维数组不改变原始数组(拷贝)
descent_a2 = a.ravel()  # 将多维数组变成一维数组,修改一维数组更改原始数组(视图)
a.shape = (3, 2)  # 更改数组维数,原始数组发生改变
a.resize((3,2)) #更改数组维数,原始数组发生改变
a.transpose()  # 数组转置
a.T  # 数组转置
a.tolist()  # 将ndarray转换成列表
a.astype(int)  # 改变数组元素的数据类型

         7、数组的组合和切割

# 数组的拼接和切割
array1 = np.arange(12).reshape(4, 3)
array2 = np.arange(12, 24, 1).reshape(4, 3)
print("####水平拼接####")
np.hstack((array1, array2))
np.column_stack((array1, array2))
np.concatenate((array1, array2), axis=1)
np.stack((array1, array2), axis=1)  # 相同行元素组合在一起
print("####垂直拼接####")
np.vstack((array1, array2))
np.row_stack((array1, array2))
np.concatenate((array1, array2), axis=0)
np.stack((array1, array2), axis=0)
print("####深度拼接####")
np.dstack((array1, array2))
print("####水平切割####")
np.hsplit(array1, 3)
np.split(array1, 3, axis=1)
print("####垂直切割####")
np.vsplit(array1, 4)
np.split(array1, 4, axis=0)
print("####深度切割####")
np.dsplit(array1,4)

        8、多维数组的视图(view)和拷贝(copy)

        在执行函数时,其中一些返回数组的拷贝,而另一些返回数组的视图,python中关于对象复制有三种类型的使用方式:赋值、浅拷贝、深拷贝

     赋值

     赋值操作传递的是对象的引用,对象改变,复制的值也会发生改变

print("####赋值####")
a = [1, 2, 3, 4, 5, 6]
b = a
print(a is b)  # True
print(id(a), id(b))  # 3401008 3401008
a[0]=100
print(b)  # [100,2,3,4,5,6] 

       上面的代码,意味着两个对象指向了同一片内存空间,赋值操作只是复制了对象的引用,没有开辟新的内存空间,修改对象a的数值,对象b的数值也发生更改。

      浅拷贝

       浅拷贝(顶层复制)把对象每一个元素的id传递给另外一个变量,浅拷贝有三种形式:切片操作工厂函数copy函数

       切片操作

          numpy中切片出来的数组都是原始数据的一个视图,并不是原数据的拷贝。python中切片出来的是原数据的一个拷贝。

print("####浅拷贝####")
print("----切片操作----")
a = [1, 2, 3]
a[1] = a[:]
print(a)  # a=[1,[1,2,3],3]
print(id(a) is id(a[1]))  # False

       上述代码先解引用得到a所指向的对象[1,2,3],然后执行[1,2,3][:]复制操作得到新的对象,内容也是[1,2,3],然后a[1]指向了这个新的对象,最后a的值为[1,[1,2,3],3]

        工厂函数

print("####浅拷贝####")
print("----工厂函数----")
a = [1, 2, 3]
a[1] = list(a)
print(a)  # a=[1,[1,2,3],3]
print(id(a) is id(a[1]))  # False

        copy函数

print("####浅拷贝####")
print("----copy函数----")
import copy

a = [1, 2, 3]
a[1] = copy.copy(a)
print(a)  # a=[1,[1,2,3],3]
print(id(a) is id(a[1]))  # False

     深拷贝

     深拷贝复制的是对象的所有元素,包括多层嵌套的元素,deepcopy本质上是递归copy。

print("----深拷贝----")
import copy

a = [1, [1, 2, 3], 3]
b = copy.deepcopy(a)
print(id(a), id(b))  # False
b[1] = 10
print(a)  # [1,[1,2,3],3]

      numpy中的视图(view)和拷贝(copy)

      视图(修改对象元素,新对象元素也会发生改变)

print("####视图####")
a = np.array([1, 2, 3])
b = a[0:2]  # 切片视图对象
c = a.view()  # 视图对象
d = a.ravel()  # 降维视图对象
a[0] = 100
print(b)  # [100,2]
print(c)  # [1,2,3]
print(d)  # [1,2,3]

    拷贝(原始数组改变,拷贝对象不改变)

import numpy as np

a = np.array([1, 2, 3])
e = np.copy(a)
a[0] = 10
print(e)  # [1,2,3]

    9、numpy广播机制

    广播机制:如果两个ndarray数组的后缘维度(即从末尾开始算起的维度)的轴长度相等或者一方为1,则他们之间可以进行广播,广播会在缺失或长度为1的维度上进行。

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

    10、花式索引

        花式索引用来获取(take)和设置(put)数组子集

array1 = np.array([1, 2, 3, 4, 5, 6])
index = [0, 2, 3]
# 取出指定索引的数组子集
print(array1.take(index))  # [1,3,4]
# 设置指定索引的数值
array1.put(index, 5)  # 全部设置为5
array1.put(index, [1, 2, 3])
array1.clip(1,2)  # clip函数表示把数组中小于1的数设置为1,大于2的数设置为2
np.where(array1 > 3)  # 筛选出数组中大于3的元素,返回元素下标
np.compress(array1 > 3, array1)  # 筛选出数组中大于3的元素,并返回元素值

猜你喜欢

转载自blog.csdn.net/qq_35511580/article/details/81168661