NumPy数组创建指南:从Python杂货铺到数据科学军营

引言:为什么我们需要NumPy?

想象一下,你正在用Python列表存储100万个温度数据。每个温度值都被Python当作一个独立的对象——有类型检查、引用计数等“豪华包装”。这就像一个杂货铺,每颗糖果都有独立包装,虽然精致但极其浪费空间

# Python列表:每个元素都是独立对象
temp_list = [36.5, 37.2, 36.8, ...] # 100万个这样的值

这时,NumPy数组登场了——它像一支纪律严明的军队,所有士兵(数据)整齐划一,共享同一种“军装”(数据类型),内存效率提升数十倍!

一、创建你的第一个NumPy数组

1.1 基础创建:从列表到数组

import numpy as np  # 标准导入,别名np是行业惯例

# 创建整数数组 - 干净利落!
a1 = np.array([1, 10, 100])
print(f"整数数组: {a1}") # 输出: [1 10 100]
print(f"数据类型: {a1.dtype}") # 输出: int64

# 创建浮点数组 - 带小数点的优雅
a2 = np.array([1.1, 2.2, 3.14])
print(f"浮点数组: {a2}") # 输出: [1.1 2.2 3.14]
print(f"数据类型: {a2.dtype}") # 输出: float64

注意:NumPy数组打印时没有逗号分隔,这是它与Python列表的视觉身份证

1.2 同化定理:NumPy的”沉默暴君”

NumPy数组有个重要特性:所有元素必须是同一种数据类型。当你试图混搭时,NumPy会默默地进行类型转换:

# 实验1:浮点数闯入整数王国
a1 = np.array([1, 10, 100])
a1[0] = 13.1 # 浮点数?砍掉小数部分!
print(f"浮入整: {a1}") # 输出: [13 10 100]

# 实验2:整数拜访浮点宫殿
a2 = np.array([1.1, 2.2, 3.14])
a2[0] = 10 # 整数?赐你小数点!
print(f"整入浮: {a2}") # 输出: [10. 2.2 3.14]

规律总结:低级类型(整数)放入高级类型(浮点)数组会被”提拔”,反之则被”降级”。

二、数组转化:NumPy的变形记

2.1 显式转化:astype()方法

# 整数数组 → 浮点数组
a1 = np.array([1, 10, 100])
a1_float = a1.astype(float) # 注意:创建新数组,不改变原数组
print(f"整数转浮点: {a1_float}") # 输出: [1. 10. 100.]

# 浮点数组 → 整数数组
a2 = np.array([1.1, 2.2, 3.14])
a2_int = a2.astype(int) # 直接截断,不是四舍五入!
print(f"浮点转整数: {a2_int}") # 输出: [1 2 3]

重要提示astype()创建新数组,原数组保持不变!

2.2 隐式转化:运算中的类型提升

# 整数数组遇到浮点数
arr = np.array([1, 10, 100])

print(f"加浮点: {arr + 1.0}") # 输出: [2. 11. 101.]
print(f"乘浮点: {arr * 1.0}") # 输出: [1. 10. 100.]
print(f"除以整数: {arr / 1}") # 输出: [1. 10. 100.] 注意!结果是浮点!

# 整数数组与浮点数组共舞
float_arr = np.array([1.1, 2.2, 3.14])
print(f"数组相加: {arr + float_arr}") # 输出: [2.1 12.2 103.14]

规律:只要运算中出现浮点数,整数数组就会”绅士地”转换为浮点数组。

三、数组维度:从一维到多维世界

3.1 理解数组形状

# 一维数组 - 一条直线
arr1d = np.array([1, 2, 3])
print(f"一维形状: {arr1d.shape}") # 输出: (3,) 注意这个逗号!

# 二维数组 - 一张表格
arr2d = np.array([[1, 2], [3, 4]])
print(f"二维形状: {arr2d.shape}") # 输出: (2, 2)

# 三维数组 - 一摞表格
arr3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(f"三维形状: {arr3d.shape}") # 输出: (2, 2, 2)

形状解读(行, 列, 深度, ...) 从外向内解读,就像俄罗斯套娃!

3.2 快速创建特殊数组

# 全是1的数组 - NumPy的"复制粘贴"
ones_1d = np.ones(3) # 一维:[1. 1. 1.]
ones_2d = np.ones((3, 4)) # 二维:3行4列的全1矩阵
ones_3d = np.ones((2, 3, 4)) # 三维:2层,每层3行4列

# 全是0的数组 - NumPy的"清零操作"
zeros_2d = np.zeros((2, 3))

# 创建序列数组 - NumPy的"等差数列"
range_arr = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]

# 创建等差数组
lin_arr = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1.]

# 创建单位矩阵
eye_mat = np.eye(3) # 3×3单位矩阵

3.3 数组变形:reshape()的魔法

# 一维变二维 - 数组的"七十二变"
arr = np.arange(12) # [0 1 2 3 4 5 6 7 8 9 10 11]

# 方法1:明确指定形状
arr_2d = arr.reshape((3, 4)) # 3行4列
print("3×4矩阵:\n", arr_2d)

# 方法2:使用-1自动计算
arr_auto = arr.reshape((3, -1)) # 3行,列数自动计算为4
print("自动计算列:\n", arr_auto)

# 二维变一维 - 数组的"返璞归真"
arr_back = arr_2d.reshape(-1) # 压扁成一维
print(f"回归一维: {arr_back}")

# 重要特性:reshape返回的是视图(view),不是副本!
# 修改视图会影响原数组,除非使用copy()

-1的妙用:告诉NumPy”你帮我算这个维度”,就像说”剩下的都归你”!

四、更多创建技巧

4.1 复制与视图

# 完全复制 - 独立个体
arr = np.array([1, 2, 3])
arr_copy = arr.copy() # 独立内存
arr_copy[0] = 99
print(f"原数组: {arr}") # 不变: [1 2 3]

# 视图 - 同一数据的窗口
arr_view = arr.view()
arr_view[0] = 99
print(f"原数组被修改: {arr}") # 改变: [99 2 3]

4.2 随机数组

# 随机数种子 - 确保可重复性
np.random.seed(42)

# 均匀分布
uniform_arr = np.random.rand(3, 4) # 0~1均匀分布

# 正态分布
normal_arr = np.random.randn(3, 4) # 标准正态分布

# 随机整数
int_arr = np.random.randint(0, 10, (3, 4)) # [0,10)的随机整数

五、总结:NumPy数组创建工具箱

方法 用途 示例
np.array() 从列表/元组创建 np.array([1,2,3])
np.arange() 创建序列 np.arange(10)
np.linspace() 创建等差数组 np.linspace(0,1,5)
np.ones() 全1数组 np.ones((3,4))
np.zeros() 全0数组 np.zeros((2,3))
np.eye() 单位矩阵 np.eye(3)
np.full() 填充数组 np.full((2,2), 7)
np.random 随机数组 np.random.rand(3,4)

核心要点回顾:

  1. 同质性是王道:NumPy数组所有元素类型必须相同
  2. 类型转换自动发生:低级类型向高级类型看齐
  3. 形状是数组的身份证(行, 列, 深度)从外向内读
  4. reshape很智能:用-1让NumPy自动计算维度
  5. 视图与副本:理解两者区别,避免意外修改

NumPy数组就像数据科学的乐高积木——标准化、可组合、高效率。掌握这些创建技巧,你就拿到了打开高效数据计算大门的钥匙!

趣味事实:在处理100万数据点时,NumPy数组比Python列表快约50倍,内存节省约75%!这可不是小数目,而是”咖啡时间去喝杯咖啡,而不是看着进度条发呆”的区别。