Numpy是python里最为重要的库之一,它提供了许多强大的处理多维数组的函数,相较于传统的列表,ndarray同样具有可变性, 但数据类型必须是统一的,此外,ndarray具备极高的内存效率与丰富的功能拓展。其多维数组的特性使得其在线性代数计算方面有着独一无二的优势
I、创建ndarray
第一种方案:直接创建
#最简单的一维数组
arr1=np.array([1,2,3,4,5])
print(arr1) #输出[1 2 3 4 5]
#多维数组,用逗号把多个一维数组隔开,外面加一个大的方括号,相当于矩阵
arr2=np.array([[1,2,3],[4,5,6]])
print(arr2) #输出[[1 2 3]
# [4 5 6]]
#规定数据类型的创建
arr3=np.array([1,2,3],dtype=np.float64)
print(arr3) #输出[1. 2. 3.]
#规定最小维度为2的创建
arr4=np.array([1,2,3],ndmin=2)
print(arr4) #输出[[1 2 3]]
第二种方案:从已有数组创建
#从已有列表创建
a=[0,0,1,4]
b=np.array(a)
print(b) #输出[0 0 1 4]
type(b) #输出numpy.ndarray
#从已有元组创建
c=(1,2,3)
d=np.array(c)
print(d) #输出[1 2 3]
type(d) #输出numpy.ndarray
#注意区别np.array和np.asarray两种函数
#numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。
#当数据源不是 ndarray(如列表、元组等)时,np.array 和 np.asarray 的行为一致,都会生成一个新的 ndarray。
#当数据源是 ndarray 时:
1.np.array 复制数据,生成新的 ndarray,即数据独立
2.np.asarray 直接返回引用,不复制数据,即数据共享
第三种方案:等差创建
#np.arange(start,stop,step,dtype)
#start:起始值,默认为0
#stop:终止值(不包含)
print(np.arange(0, 10, 2)) # 输出: array([0, 2, 4, 6, 8])
#np.linspace(start,stop,num,endpoint,dtype)
#start:起始值,默认为0
#stop:终止值(包含)
#num:生成的等间隔样例数量,默认为50
#endpoint:序列中是否包含stop值,默认为True
print(np.linspace(0, 1, 5)) # 输出: array([0., 0.25, 0.5, 0.75, 1.])
#可用reshape等函数将等差创建的一维数组延展到多维
第四种方案:一个数字填满整个数组
#numpy.zeros(shape, dtype , order )
#shape:数组形状
#dtype:数据类型,可选,默认浮点数
#order:可选,有"C"和"F"两个选项,分别代表,行和列
arr1 = np.zeros(5)
print(arr1)# 输出: [0. 0. 0. 0. 0.]
arr2 = np.zeros((2, 3))
print(arr2) # 输出: [[0. 0. 0.]
# [0. 0. 0.]]
#类似的还有: numpy.ones(shape, dtype , order )
#numpy.full(shape, fill_value, dtype, order)
# 创建长度为5的一维数组,填充值为7
arr_1d = np.full(5, 7)
print(arr_1d) # 输出: [7 7 7 7 7]
# 创建形状为(2, 3)的二维数组,填充值为8
arr_2d = np.full((2, 3), 8)
print(arr_2d) # 输出: [[8 8 8]
# [8 8 8]]
#由于numpy里初始化空数组的函数为往数组里随机添加数字,往往实际使用时会选择用numpy.zeros之类的函数代替
II、索引与切片
#ndarray的切片具有极强的灵活性,有些类似于列表
arr = np.array([1,2,3,4,5,6,7,8,9])
print(arr[5:8]) #输出:[6 7 8]
arr[5:8]=10
print(arr) #输出:[ 1 2 3 4 5 10 10 10 9]
#值得注意的是,这样快捷的切片方式是浅拷贝,这也意味着对切片部分的改动,会影响原有数组
arr1 = np.array([1,2,3,4,5,6,7,8,9])
arr1_slice= arr1[5:8]
arr1_slice[:]=88
print(arr1) #输出:[ 1 2 3 4 5 88 88 88 9]
#如果想要避免这种情况,可以使用copy函数深拷贝
arr2 = np.array([1,2,3,4,5,6,7,8,9])
arr2_slice= arr2[5:8].copy()
#接下来讲讲多维数组的切片
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 取第一行
print(arr2d[0]) # 输出: [1 2 3]
# 取第一列
print(arr2d[:, 0]) # 输出: [1 4 7]
# 取前两行
print(arr2d[:2]) # 输出: [[1 2 3]
# [4 5 6]]
# 取前两列
print(arr2d[:, :2]) # 输出: [[1 2]
# [4 5]
# [7 8]]
# 选取任意你想要的部分,如:
print(arr2d[:2, 1:]) # 输出: [[2 3]
# [5 6]]
#总结:第一位表示axis0的取向(纵),第二位表示axis1的取向(横)
布尔索引与数据筛选
#布尔索引(Boolean Indexing)是NumPy中一种强大且高效的数据选择方法,它允许你使用布尔值(True/False)数组来选择数组中的元素
arr = np.array([1, 2, 3, 4, 5])
mask = np.array([True, False, True, False, True]) #布尔掩码(副本)
print(arr[mask]) # 输出: [1 3 5]
# 这里示范使用布尔索引筛选出数组中的奇数元素
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
mask = arr % 2 == 1
print(mask) # 输出:[ True False True False True False True False True]
print(arr[mask]) # 输出: [1 3 5 7 9]
#判定条件的设置非常灵活
arr = np.array([10, 20, 30, 40, 50])
print(arr[arr > 30]) #输出: [40 50]
print(arr[(arr > 20) & (arr < 50)]) #输出: [30 40]
#多维数组也能用
arr1 = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(arr1[arr1 > 5]) # [6 7 8 9]
arr2 = np.array([[1, 2], [3, 4], [5, 6]])
mask = np.array([True, False, True])
print(arr2[mask]) # 选择第0行和第2行
# 输出:
# [[1 2]
# [5 6]]
布尔索引与数据处理
#批量修改元素数值
arr = np.array([1, 2, 3, 4, 5])
arr[arr > 3] = 99
print(arr) # [ 1 2 3 99 99]
#清洗异常数值
data = np.array([1, 2, np.nan, 4, 5, np.nan, 7])
clean_data = data[~np.isnan(data)]
print(clean_data) # [1. 2. 4. 5. 7.]
布尔索引与图像处理
import numpy as np
import matplotlib.pyplot as plt
# 生成100x100的灰度图像(0-99)
image = np.zeros(shape=(100, 100), dtype=np.uint8)
for i in range(100):
image[i, :] = i # 每行像素值等于行号
# 布尔索引示例1:将大于50的像素设为255(白色)
thresholded = image.copy()
thresholded[thresholded > 50] = 255
# 布尔索引示例2:创建黑白相间的条纹图案
striped = image.copy()
striped[(striped % 20) < 10] = 0 # 每20像素中前10设为黑色
striped[(striped % 20) >= 10] = 255 # 后10设为白色
# 布尔索引示例3:创建中心高亮区域
center_highlight = image.copy()
y, x = np.ogrid[:100, :100]
mask = (x-50)**2 + (y-50)**2 <= 30**2 # 半径为30的圆形区域
center_highlight[mask] = 255 # 圆形区域内设为白色
# 显示所有图像
plt.figure(figsize=(15, 10))
# 原始图像
plt.subplot(2, 2, 1)
plt.imshow(image, cmap='gray')
plt.title("Original Image")
plt.axis('off')
# 阈值处理
plt.subplot(2, 2, 2)
plt.imshow(thresholded, cmap='gray')
plt.title("Threshold >50")
plt.axis('off')
# 条纹图案
plt.subplot(2, 2, 3)
plt.imshow(striped, cmap='gray')
plt.title("Striped Pattern")
plt.axis('off')
# 中心高亮
plt.subplot(2, 2, 4)
plt.imshow(center_highlight, cmap='gray')
plt.title("Center Highlight")
plt.axis('off')
plt.tight_layout()
plt.show()
花式索引:更加灵活的切片(副本)
arr = np.array([10, 20, 30, 40, 50, 60, 70])
print(arr[[1, 3, 5]]) # 输出: [20 40 60]
# 元素可以重复选择
print(arr[[0, 0, 2, 2, 2]]) # 输出: [10 10 30 30 30]
# 可以改变顺序
print(arr[[6, 4, 2, 0]]) # 输出: [70 50 30 10]
# 多维数组里的使用
arr_2d = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]])
# 选择第0行和第2行
print(arr_2d[[0, 2]])# 输出: [[1 2 3]
# [7 8 9]]