Code - Numpy练习.py

import numpy as np

ndarray 是numpy的核心数据结构,多维数组对象,用于存储同类型数据的集合 相比python 原生列表,具有更有的内存效率,运算速度和多维操作能力,是后续数据处理的基础载体。

dtype 数组元素的数据类型,用于指定存储数据的类型(如证书、浮点数、字符串等等)

代码示例

1. 创建 ndarray 并查看核心属性

arr = np.array([[1, 2], [3, 4], [5, 6]], dtype=np.float32)
print(arr.shape) # 形状 (3, 2)
print(arr.dtype) # 类型 float32
print(arr.strides) # 步长 (8, 4) C风格:每行占 2*4=8 字节,每元素占 4 字节

2. 修改 dtype(会创建新数组,原数组不变)

arr_int = arr.astype(np.int32)
print("修改 dtype 后的数据类型:", arr_int.dtype) # int32

数组创建、索引、切片

arr1 = np.array([1, 2, 3, 4]) # 一维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]]) # 二维数组

2. 固定值数组

arr_zero = np.zeros((2, 3), dtype=np.float32) # 全0数组
arr_one = np.ones((2, 3), dtype=np.float32) # 全1数组
arr_full = np.full((2, 3), fill_value=10) # 固定值填充 全是10
arr_eye = np.eye(3) # 单位矩阵(对角为1,其余为0)

3. 序列数组

arr_arange = np.arange(0, 10, step=2) # 0到10(不包含10),步长2 #[0 2 4 6 8]
arr_linspace = np.linspace(

0, 10, 5

) # 0到10(包含10),均分5个元素 [ 0. 2.5 5. 7.5 10. ]

二、索引

1. 一维数组索引

print(arr1[2]) # 3 下标从0开始

2. 二维数组索引(行下标, 列下标)

print(arr2[1, 0]) # 输出 4(第二行第一列元素)

3. 布尔索引

mask = arr1 > 1
print(arr1[mask]) # [2 3 4]

4. 整数数组索引(提取指定下标元素)

print(arr1[[0, 2, 3]]) # 输出 [1 3 4]

三、切片

1. 一维数组切片(start:end:step)

print(arr_arange[1:4:1]) # [2 4 6] (从下标1到3,步长1)

2. 二维数组切片(行切片, 列切片)

print(arr2[0:2, 0:1]) # 前2行,前1列 输出 [[1], [4]]

print(arr2[:, :]) # 所有行,所有列 输出 [1 2 3]

3. 切片视图特性

arr_slice = arr2[1:3]
print(arr_slice) # [[4 5 6]]
arr_slice0 = 99
print(arr2) # 原数组被更改了[ 1 2 3]

4. 生成切片副本(避免修改原数组)

arr_slice2 = arr2[1:3].copy()
arr_slice20 = 99
print(arr_slice2) # [[99 99 6]]
print(arr2) # [ 1 2 3]

广播机制、向量化运算

广播机制:NumPy 中不同形状数组进行运算时,自动调整数组形状以满足运算条件的规则,无需手动扩展数组维度,简化代码并提升效率。

向量化运算:直接对数组整体进行运算,替代 Python 原生的循环遍历,依托底层 C 语言实现,运算速度远超循环(尤其是大数据量场景)。

arr3 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr3 + 2) # [3 4 5] # 标量2广播为(2,3)数组,输出每个元素加2的结果

arr3d = np.array([10, 20, 30])
print(arr3 + arr3d) # [11 22 33] # arr3d(2,3)数组,对应元素相加

3. 不满足广播条件的情况(报错)

try:

arr2d = np.array([[1], [2]])

arr3d = np.array([1, 2])

print(arr2d + arr3d) # 形状(2,1)与(2,)可广播,输出(2,2)数组

arr_err = np.array([[1, 2], [3, 4]])

arr_err2 = np.array([1, 2, 3])

print(arr_err + arr_err2) # 形状(2,2)与(3,)无法广播,报错

except ValueError as e:

print("广播错误:", e)

二、向量化运算

1. 数组元素级运算(替代循环)

arr_a = np.arange(10)
print(arr_a) # [0 1 2 3 4 5 6 7 8 9]
arr_b = np.arange(10, 20)
print(arr_b) # [10 11 12 13 14 15 16 17 18 19]

向量化加法(高效)

arr_c = arr_a + arr_b
print(arr_c) # [10 12 14 16 18 20 22 24 26 28]

2. 向量化函数(np.vectorize,适合简单自定义函数)

def func(x):

return x * 2 + 1

vec_func = np.vectorize(func) # np.vectorize,适合简单自定义函数
arr_result = vec_func(arr_a[:10])
print(arr_result) # [ 1 3 5 7 9 11 13 15 17 19]

基础聚合函数

1. 核心定义与作用

聚合函数用于对数组元素进行统计汇总运算,将多维数组压缩为标量或低维数组,是数据描述性统计的基础工具,常见函数包括求和(sum)、均值(mean)、最大值(max)、最小值(min)、极值索引(argmax/argmin)、方差(var)、标准差(std)等。

narr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.float32)

1. 全局聚合(对整个数组运算)

print(np.sum(narr)) # 总和 输出 78.0
print(np.mean(narr)) # 输出 6.5
print(np.max(narr)) # 最大值 12.0
print(np.argmax(narr)) # 最大值索引 输出 11(一维展开后的下标)
print(np.var(narr)) # 方差 11.11.916667
print(np.std(narr)) # 标准差1.7078252

2. 按轴聚合(axis=0 按列,axis=1 按行)

print(np.sum(narr, axis=0)) # 按列求和 [15. 18. 21. 24.]
print(np.mean(narr, axis=1)) # 按行求均值 [ 2.5 6.5 10.5]
print(np.argmax(narr, axis=0)) # 按列求最大值索引 输出 [2 2 2 2]
print(np.min(narr, axis=1)) # 按行求最小值[1. 5. 9.]

3. 聚合时忽略NaN值(需用nan开头的函数)

cparr = narr.copy()
cparr[1, 2] = np.nan
cparr[2, 3] = np.nan
print(np.sum(cparr)) # 含nan值,直接sum = nan
print(np.nansum(cparr)) # 忽略nan值 59.0

4. 累计聚合(cumsum, cumprod)

print(

np.cumsum(narr, axis=1)

) # 按行累计求和 [ 1. 3. 6. 10.[ 9. 19. 30. 42.]]

随机数生成

NumPy 的 random 模块提供丰富的随机数生成功能,可生成符合不同分布(均匀分布、正态分布、泊松分布等)的随机数组,用于模拟实验、数据扩充、打乱数据集等场景

1. 设置随机种子(确保结果可复现)

np.random.seed(42) # 种子固定后,每次生成的随机数相同

2. 生成均匀分布随机数([0,1)区间)

arr_unif = np.random.rand(2, 3) # 形状(2,3)
print(

arr_unif

) # 种子固定后每次运行结果都会保持一致 #[[0.37454012 0.95071431 0.73199394] [0.59865848 0.15601864 0.15599452]]

3. 生成正态分布随机数(均值0,标准差1)

arr_norm = np.random.randn(3, 2)
print(arr_norm) # -0.46947439 0.54256004]

生成指定均值和标准差的正态分布

arr_norm2 = np.random.normal(loc=5, scale=2, size=(2, 2)) # loc=均值,scale=标准差
print(arr_norm2) # [5.48392454 1.17343951]

4. 生成整数随机数

[low, high)区间整数

arr_int = np.random.randint(low=0, high=5, size=(2, 2))
print(arr_int) # [2 1]

随机选择整数(可重复)

arr_choice = np.random.choice([1, 3, 5, 7], size=(3, 3))
print(arr_choice) # [7 5 3[5 7 5]]

5. 打乱数组(in-place操作,修改原数组)

rarr = np.arange(10)
print(rarr) # [0 1 2 3 4 5 6 7 8 9]
np.random.shuffle(rarr)
print(rarr) # [9 1 5 0 6 7 4 2 8 3]

不修改原数组的打乱(返回副本)

arr2 = np.arange(10)
arr_shuffled = np.random.permutation(arr2)

6. 生成其他分布随机数 ?

arr_poisson = np.random.poisson(lam=2, size=(2, 3)) # 泊松分布(lam=均值)
arr_binom = np.random.binomial(

n=10, p=0.5, size=5

) # 二项分布(n=试验次数,p=成功概率)

numpy数据清洗

1. 生成含缺失值的数组

errarr = np.array(

[[1.0, 2.0, np.nan], [4.0, np.inf, 6.0], [np.nan, 8.0, -np.inf]], dtype=float

)

检测NaN

is_nan = np.isnan(errarr)
print(is_nan)

检测inf(含正无穷、负无穷)

is_inf = np.isinf(errarr)
print(is_inf)

检测所有缺失值(NaN + inf)

is_missing = np.isnan(errarr) | np.isinf(errarr)

统计缺失值数量

print(np.sum(is_missing)) # 统计缺失值
print(np.sum(is_missing, axis=0)) # 按列统计缺失值

条件清洗(np.where, np.select)

生成待清洗数据

data = np.array([[1, 20, 3], [15, 5, 25], [8, 30, 12]], dtype=float)

一、布尔掩码(筛选与标记)

1. 筛选满足条件的元素(值大于10)

mask = data > 10
data_filtered = data[mask]
print(data_filtered) # [20. 15. 25. 30. 12.]

2. 标记满足条件的元素(值大于18标记为1,否则为0)

mask_mark = np.where(data > 18, True, False)
print(data[mask_mark]) # [20. 25. 30.]

3. 多条件组合掩码(值在[5,20]之间)

mask_multi = (data >= 5) & (data <= 20)
data_multi_filtered = data[mask_multi]
print(data_multi_filtered) # [20. 15. 5. 8. 12.]

二、np.where(二分支条件替换)

条件:值小于10替换为10,否则保持原值(下限填充)

data_where = np.where(data < 10, 10, data)
print(data_where) # [10. 20. 10.[10. 30. 12.]]

多维度条件(按列设置不同条件)

data_where_multi = data.copy()
data_where_multi[:, 0] = np.where(data[:, 0] < 10, 0, data[:, 0]) # 第一列处理
data_where_multi[:, 1] = np.where(data[:, 1] > 20, 20, data[:, 1]) # 第二列处理
print(data_where_multi) # [ 0. 20. 3.[ 0. 20. 12.]]

三、np.select(多分支条件替换)

条件:<5 → 0;5-15 → 原值;>15 → 15(三分支缩尾)

conditions = [data < 5, (data >= 5) & (data <= 15), data > 15]
choices = [0, data, 15]
data_select = np.select(conditions, choices, default=data)

多分支分类(根据值范围分类为低、中、高)

conditions_label = [data < 10, (data >= 10) & (data <= 20), data > 20]
choices_label = ["低", "中", "高"]
data_label = np.select(conditions_label, choices_label, default="未知")

添加新评论