ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

一文学完numpy使用

一文学完numpy使用 个人笔记目录一、Numpy与ndarray概述1、numpy2、ndarray的核心特征二、底层内存本质--data、shape与strides三、ndarray的创建1、基础构造2、预定义形状填充3、基于数值范围生成4、特殊矩阵5、随机数组四、基本属性五、索引和切片1、基础索引2、切片语法3、高级索引花式索引与布尔索引 -----副本陷阱4、三维以及上省略号六、数组运算与广播机制1、算术运算2、广播Broadcasting的底层“零拷贝”实现3、矩阵乘法点积七、数学与统计函数1、常用数学函数2、浮点数与“银行家舍入”3、统计函数4、比较、逻辑与条件替换索引用法八、轴Axis的消失与保留九、数组变形与平展1、多维转一维2、重塑形状十、合并数组1、np.concatenate() – 沿指定轴拼接默认axis 02、便捷函数十一、唯一值与去重np.unique(arr) – 返回排序后的唯一值十二、金融/时间序列进阶十三、实战任务1温度统计任务2成绩统计与分位数任务3随机数组操作含奇数替换任务4销售额分析含最值索引任务5唯一值频次统计一、Numpy与ndarray概述1、numpyNumPy是 Python 科学计算的基础库提供高性能的多维数组对象ndarray。底层用 C 语言实现支持向量化运算无需显式循环计算效率远超 Python 原生列表。2、ndarray的核心特征特征说明多维性支持 0 维标量、1 维向量、2 维矩阵及更高维张量同质性所有元素类型必须一致如全部为 int64 或 float64高效性连续内存存储支持广播和元素级并行计算维度观察技巧定义数组时最左边起有几个左中括号[就是几维数组。二、底层内存本质--data、shape与stridesndarray 存储在连续内存块中。NumPy 数组不仅仅是数据它包含三个核心元数据data指向内存块的指针。shape数组各维度的大小。strides步长表示从当前维度的一个元素跳到下一个元素所需的字节数。转置T不复制数据arr.T只是交换了shape和strides中的行列值内存数据原封不动所以转置是O(1) 操作极快。视图View vs 副本Copyarr[::2]步长切片、arr.ravel()、arr.reshape(-1)通常返回视图共享内存。而arr.flatten()和花式索引如arr[[0,1]]返回副本新内存。import numpy as np arr np.arange(6).reshape(2,3) print(arr.strides) # 输出 (24, 8) 假设 int64 占 8 字节 arr_T arr.T print(arr_T.strides) # 输出 (8, 24) —— 步长交换数据未动三、ndarray的创建1、基础构造a1 np.array([1, 2, 3, 4, 5]) # 一维 a2 np.array([[1, 2], [3, 4], [5, 6]]) # 二维 a3 np.array([[[1,2,3],[2,3,4]], [[3,4,5],[4,5,6]]]) # 三维2、预定义形状填充函数说明示例np.zeros(shape)全 0 数组np.zeros((2,3))np.ones(shape)全 1 数组np.ones((2,3), dtypeint)np.empty(shape)未初始化随机值np.empty((2,2))np.full(shape, value)指定填充值np.full((3,3), 2026)np.zeros_like(arr)/np.ones_like(arr)以 arr 的形状创建全 0/1dtype可指定为np.int64、np.float32、bool等NumPy 会自动向上转型如整数浮点→浮点。3、基于数值范围生成函数说明注意np.arange(start, stop, step)等差数列不含 stop类似rangenp.linspace(start, stop, num)等间隔取 num 个点包含stopnp.logspace(start, stop, num, base)对数间隔base 的幂默认 base10np.arange(1, 10, 2) # [1, 3, 5, 7, 9] np.linspace(0, 10, 6) # [0., 2., 4., 6., 8., 10.] np.logspace(2, 4, 3, base10) # [100., 1000., 10000.]4、特殊矩阵函数说明np.eye(N)单位矩阵对角线为 1np.diag([a,b,c])对角矩阵仅主对角线有值A A.T构造对称矩阵任何矩阵加其转置均为对称矩阵5、随机数组函数分布参数np.random.rand(d0,d1,...)均匀分布 [0,1)形状参数直接给出np.random.uniform(low, high, size)均匀分布 [low, high)size 为元组np.random.randint(low, high, size)均匀整数 [low, high)np.random.randn(d0,d1,...)标准正态分布全局种子的污染问题与最佳实践np.random.seed(42)设置的是全局随机种子在复杂项目中会导致随机性被意外锁定。# 使用独立的 Generator 对象隔离全局影响 rng np.random.default_rng(seed42) arr1 rng.random((3,3)) # 均匀分布 arr2 rng.integers(0, 10, (2,2)) # 随机整数四、基本属性属性说明示例ndim数组维数arr.ndimshape形状各维度大小元组arr.shape→ (2, 3, 4)size元素总个数arr.size 2×3×4 24dtype元素数据类型arr.dtype→int64T转置对二维矩阵有效零成本视图arr.Tstrides步长字节数揭示内存布局arr.strides五、索引和切片1、基础索引使用[行, 列, ...]进行多维索引支持负数从末尾开始。arr np.random.randint(1,10,(3,8)) print(arr[2,3]) # 第三行第四列2、切片语法每个维度独立切片用逗号分隔。基础切片 (start:stop)返回视图修改会影响原数组。arr2d np.random.randint(1,10,(5,8)) print(arr2d[0:2, 2:]) # 前两行从第3列开始 print(arr2d[:, ::2]) # 所有行每隔一列取一个3、高级索引花式索引与布尔索引 -----副本陷阱布尔索引/花式索引 (arr[[0,2], [1,3]])返回副本因为索引不连续无法用步长表示。⚡ 巨坑警告arr[arr 5][0] 999修改的是筛选后的副本原数组纹丝不动✅ 正确原地修改方法直接使用布尔索引赋值。arr np.array([1, 6, 3, 8]) arr[arr 5] 999 # 直接在原数组上操作 print(arr) # [ 1 999 3 999]4、三维以及上省略号arr3d np.random.randint(0,10,(3,4,5)) print(arr3d[..., 1:2]) # 使用 ... 省略中间所有维度六、数组运算与广播机制1、算术运算支持,-,*,/,//,%,**。标量0维可与任意维度运算。a np.array([1,2,3]); b np.array([4,5,6]) print(a b) # [5 7 9] print(a * 2) # [2 4 6]2、广播Broadcasting的底层“零拷贝”实现表面规则形状匹配或维度为 1 时可以广播。深层机理零拷贝虚拟展开当某个维度大小为 1 时NumPy 将该维度的步长设为 0。这意味着无论取该维度的哪个索引它都返回同一个内存地址的数据物理内存绝不会真的复制数据。广播的规则两个数组要是能广播必须从尾到头逐级维度比较满足以下其中之一即可前提不是0维0维一定可广播标量可以和任意维度数组计算1、两个维度相等2、其中一个维度为13、其中一个维度缺失该维度不存在例null 1 25 1 1检验是否可以广播步骤1、形状右对齐2、从尾巴往头比3、要么相等要么有1要么报错arr_A shape: (4, 3, 2) arr_B shape: (3, 1) 右对齐从右往左比2 vs 1√因为B有13 vs 3√4 vs 无√维度缺失自动补1 可广播3、矩阵乘法点积运算符 或np.dot()。左矩阵列数 右矩阵行数。A np.array([[1,2,3],[4,5,6]]) # (2,3) B np.array([[1,2],[3,4],[5,6]]) # (3,2) print(A B) # (2,2)A np.array([[1,2,3],[4,5,6]]) # (2,3) B np.array([[1,2],[3,4],[5,6]]) # (3,2) print(A B) # (2,2)七、数学与统计函数1、常用数学函数函数说明np.sqrt/np.exp/np.exp2平方根 / e^x / 2^xnp.log/np.log2/np.log10自然对数 / 以2为底 / 以10为底np.power/np.abs幂运算 / 绝对值np.ceil/np.floor向上/向下取整np.isnan检查缺失值2、浮点数与“银行家舍入”现象np.round(2.5)居然等于2.0而不是3.0。深层机理这是 IEEE 754 标准的“四舍六入五成双”银行家舍入法目的是减小统计偏差。2.5-2(偶)3.5-4(偶)。工程铁律如果业务要求严格如金额永远不要用round做财务计算请使用 Python 的decimal.Decimal模块或将数值放大 100 倍转为整数分int计算。3、统计函数函数说明np.sum/np.mean和 / 平均值np.median中位数np.var/np.std方差 / 标准差np.percentile(arr, q)百分位数q 为 0~100np.max/np.min/np.argmax/np.argmin最值及索引np.cumsum/np.cumprod累计和 / 累计积分位数计算设有一组已排序的数据[1, 3, 5, 7, 9, 11]共6个数n6想算25%分位数Q1。门派一INC 方法最常用Excel PERCENTILE.INC / Python numpy.percentile 默认位置公式位置1(n−1)×p把一组数据从第1名排到第n名整个排名区间长度为 (n-1)。我们想知道在百分之 p即 p×100% 的位置上对应的是第几名。计算1(6−1)×0.2511.252.25含义位置在第2个数3和第3个数5之间且偏向第2个数。小数部分X差值结果30.25×(5−3)3.5print(np.percentile(np.array([23,34,56,66,76,90,102,120]),60)) #78.84、比较、逻辑与条件替换函数说明np.greater/np.less/np.equal元素级比较np.logical_and/or/not逻辑运算np.any/np.all是否存在 True / 是否全为 True非零np.where(condition, x, y)条件筛选替换x/y可为标量或数组索引用法# 验证where用法 a np.array([1,3,1,2,4,5,1,2,3]) print(np.where(a1)[0]) b np.array([2,1,3,4,0]) print(b) c np.array([32,67,78,89,21]) print(c) print(c[b]) [0 2 6] [2 1 3 4 0] [32 67 78 89 21] [78 67 89 21 32] 例题某电商平台记录了10件商品的销售数据: python product_ids np.array([101,102,103,104,105,101,102,106,103,101]) prices np.array([299,199,399,159,499,299,199,89,399,299]) sales np.array([5,3,2,8,1,4,6,10,3,7]) 要求: 1. 找出有哪些不同的商品ID 2. 统计每个商品ID出现的次数 3. 计算每个商品的总销售额(单价× 销量),并找出销售额最高的商品ID 4. 使用np.unique()的return_index 参数,找出各商品首次出现的记录位置,并提取这些记录的商品ID、单价和销量 product_ids np.array([101,102,103,104,105,101,102,106,103,101]) prices np.array([299,199,399,159,499,299,199,89,399,299]) sales np.array([5,3,2,8,1,4,6,10,3,7]) # 第一问 unique_ids np.unique(product_ids) print(unique_ids) # 第二问 unique_ids ,count np.unique(product_ids,return_countsTrue) #return_counts 如果设置为 True函数会返回一个包含每个唯一元素出现次数的数组。 for uid, c in zip(unique_ids, count): print(f商品 {uid}: 出现 {c} 次) #第三问 total_sales prices * sales print(第三问,total_sales) total_revenue[] for uid in unique_ids: record (product_ids uid) revenue np.sum(total_sales[record]) total_revenue.append(revenue) total_revenue np.array(total_revenue) best_id unique_ids[np.argmax(total_revenue)] print(best_id) print(*50) #第四问 unique_ids, first_indices np.unique(product_ids, return_indexTrue) # return_index 原理返回每个唯一值在原数组中第一次出现的位置索引。 print(第四问,first_indices) first_ids product_ids[first_indices] first_prices prices[first_indices] first_sales sales[first_indices] print(first_ids) print(first_prices) print(first_sales)八、轴Axis的消失与保留axis指的是“被折叠聚合的维度”。聚合后该维度消失。对于shape(3, 2, 4)np.sum(axis0)消除第一维 →shape(2, 4)。np.sum(axis1)消除第二维 →shape(3, 4)。保持维度Keepdims加上keepdimsTrue结果shape(1, 2, 4)便于后续广播。# 轴 通俗来讲就是数组元素沿着那个维度去操作聚合 sum mean# 简单来记 矩阵中axis -- 0列 压缩行 1行压缩列# # axis意思理解为:消除维度 0 1 2 3... 表示形状中从左到右的维度下标九、数组变形与平展1、多维转一维方法返回类型是否影响原数组arr.flatten()副本新内存否arr.ravel()视图尽量是修改影响原数组arr.reshape(-1)视图尽量是修改影响原数组2、重塑形状新形状元素总数必须一致可用-1自动推断。reshape就是重新排列数组的形状不改变数据本身只改变数据的包装方式。import numpy as np arr np.arange(24) # [0,1,2,...,23]共24个元素 print(arr.shape) # (24,) # 方法1直接传展开参数 arr2 arr.reshape(2, 3, 4) print(arr2.shape) # (2, 3, 4) # 方法2传元组等价 arr3 arr.reshape((2, 3, 4)) print(arr3.shape) # (2, 3, 4) #总元素数必须匹配 arr np.arange(24) # 24个元素 arr.reshape(2, 3, 4) # ✅ 2×3×4 24 arr.reshape(3, 8) # ✅ 3×8 24 arr.reshape(4, 6) # ✅ 4×6 24 arr.reshape(5, 5) # ❌ 5×5 25 ≠ 24报错-1当你懒得算某个维度该是多少时传-1NumPy 自动推断arr np.arange(24) arr.reshape(3, -1) # 3行列数自动算24÷38 → shape(3, 8) arr.reshape(2, -1, 4) # 2层4列行数自动算24÷(2×4)3 → shape(2, 3, 4) arr.reshape(-1) # 全部摊平 → shape(24,)特性reshaperesize返回值返回新数组视图原地修改返回None是否改变原数组❌ 不改变✅ 直接改原数组元素数不匹配时❌ 报错⚠️ 截断或补零使用场景临时改变形状做运算永久改变数组大小十、合并数组1、np.concatenate()– 沿指定轴拼接默认axis 0a np.random.randint(0,10,(2,3)) b np.random.randint(0,10,(2,3)) c np.concatenate((a, b), axis0) # (4,3) d np.concatenate((a, b), axis1) # (2,6)2、便捷函数np.vstack((a,b))– 垂直堆叠axis0np.hstack((a,b))– 水平堆叠axis1十一、唯一值与去重配合切片np.unique(arr)– 返回排序后的唯一值return_indexTrue同时返回唯一值首次出现的索引return_countsTrue同时返回每个唯一值的出现次数axis指定按行或按列去重arr np.array([2,1,2,3,1,4,3,5,5]) uniq, counts np.unique(arr, return_countsTrue) print(uniq) # [1 2 3 4 5] print(counts) # [2 2 2 1 2] # 二维按行去重 mat np.array([[1,2],[1,2],[3,4]]) print(np.unique(mat, axis0)) # [[1,2],[3,4]]十二、金融/时间序列进阶cumsum累积和常用于计算资产净值的“复利增长曲线”。np.diff差分计算相邻元素的差值是cumsum的逆运算用于将“价格序列”转为“日收益率序列”。prices np.array([100, 102, 101, 105]) returns np.diff(prices) / prices[:-1] # [0.02, -0.0098, 0.0396]十三、实战习题关注https://gitee.com/leecyldy/aistudy.git任务1温度统计pythontp np.array([28,30,29,31,32,30,29]) print(np.mean(tp), np.max(tp), np.min(tp)) print(np.sum(tp 30)) # 超过30℃的天数任务2成绩统计与分位数pythonscores np.array([85,90,78,92,88]) print(np.mean(scores), np.median(scores), np.std(scores)) print(np.percentile(scores, 60)) # 60%分位数 print(scores * 0.1) # 转为10分制任务3随机数组操作含奇数替换pythonarr np.random.randint(0,10,(3,4)) col_max np.max(arr, axis0) row_min np.min(arr, axis1) arr_odd np.where(arr % 2 1, -1, arr) # 奇数变-1任务4销售额分析含最值索引pythonsales np.array([120,135,110,125,130,140]) print(np.sum(sales), np.mean(sales), np.var(sales)) print(np.argmax(sales)1, np.argmin(sales)1) # 最高/最低月份任务5唯一值频次统计pythonarr np.array([2,1,2,3,1,4,3,5,5]) uniq, counts np.unique(arr, return_countsTrue)
返回列表