商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > NumPy中flatten()函数的具体使用

NumPy中flatten()函数的具体使用

  发布于2026-07-17 阅读(0)

扫一扫,手机访问

一、flatten() 核心定义

我们先从最基础的说起。flatten() 是 NumPy 数组(ndarray)自带的一个方法,它的核心工作很简单——“把数组捋平”。无论你手里的是二维、三维还是更高维度的数组,它都能把所有元素按照指定顺序排成一列,变成一个一维数组。

更重要的是,它返回的是一个全新的独立数组,跟原来的数组不共享内存。这意味着你改完新数组,原数组纹丝不动,安全得很。

NumPy中flatten()函数的具体使用

简单理解一下:比如一个 2 行 3 列的二维数组,或者一个 2×3×4 的三维立体数据,flatten() 都会把所有元素按顺序一股脑排成一行。修改展平后的结果,完全不影响原始数组。

核心语法

flattened_arr = arr.flatten(order='C')
  • arr:待展平的 NumPy 数组(任意维度)
  • order:可选参数,控制元素展平的顺序(默认是 'C'
  • 返回值:一个全新的一维数组(独立内存)

二、基础用法(不同维度数组展平)

示例 1:二维数组展平(最常用)

我们先从最常用的二维数组说起。

import numpy as np
# 原始二维数组(2行3列)
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
print("原始二维数组:\n", arr_2d)
print("原始形状:", arr_2d.shape)  # (2, 3)
# 展平为一维数组(默认顺序)
arr_flat = arr_2d.flatten()
print("\n展平后的一维数组:", arr_flat)
print("展平后形状:", arr_flat.shape)  # (6,)

输出结果

原始二维数组:

[[1 2 3]

[4 5 6]]

原始形状:(2, 3)

展平后的一维数组:[1 2 3 4 5 6]

展平后形状:(6,)

可以看到,原来两行三列的数据,被拉成了一行六个元素。这就是 flatten() 最核心的能力。

示例 2:三维数组展平

三维数组可以理解为“多个二维矩阵的集合”。flatten() 会按照顺序,把这些矩阵里的元素全部拼接起来。

import numpy as np
# 原始三维数组(2个3行2列的矩阵)
arr_3d = np.array([
    [[1, 2], [3, 4], [5, 6]],
    [[7, 8], [9, 10], [11, 12]]
])
print("原始三维数组形状:", arr_3d.shape)  # (2, 3, 2)
# 展平为一维
arr_flat = arr_3d.flatten()
print("展平后的数组:", arr_flat)
print("展平后形状:", arr_flat.shape)  # (12,)

输出结果

原始三维数组形状:(2, 3, 2)

展平后的数组:[ 1 2 3 4 5 6 7 8 9 10 11 12]

展平后形状:(12,)

原来有 2 个矩阵,每个 3 行 2 列,总共 12 个元素。展平后,它们整整齐齐排成了一行。

三、关键参数:order(展平顺序)

order 参数决定了元素是按什么顺序读出来的。最常用的是下面三个:

order 值含义读取顺序示例(二维数组 [[1,2],[3,4]])
'C'(默认)C 风格(行优先)先填满每一行,再读下一行[1,2,3,4]
'F'Fortran 风格(列优先)先填满每一列,再读下一列[1,3,2,4]
'A'按数组在内存中的存储顺序如果数组是 C 风格存储就等价于 'C',否则等价于 'F'通常和 'C' 一致

简单来说,如果把数组想象成一个矩阵:'C' 风格展平,就是“先按行读”;'F' 风格展平,就是“先按列读”。

示例:不同 order 的展平效果

import numpy as np
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
# C风格(行优先,默认)
flat_c = arr_2d.flatten(order='C')
# F风格(列优先)
flat_f = arr_2d.flatten(order='F')
print("C风格展平(行优先):", flat_c)  # [1 2 3 4 5 6]
print("F风格展平(列优先):", flat_f)  # [1 4 2 5 3 6]

看到了吗?同样的数据,'C' 从第一行开始,从左到右读;'F' 从第一列开始,从上到下读。顺序不同,结果自然不一样。

四、flatten() vs reshape(-1)(核心对比!)

这是新手最容易搞混的地方。两者都能把数组展平成一维,但有一个本质区别:内存是否共享

特性flatten()reshape(-1)
返回值新的独立数组(拷贝)原数组的视图(共享内存)
内存占用高(复制一份数据)低(仅修改形状,不复制数据)
修改影响修改展平数组,原数组不变修改展平数组,原数组同步修改
速度较慢(需拷贝数据)极快(仅调整形状)
语法arr.flatten()arr.reshape(-1)

实战对比示例:

import numpy as np
arr = np.array([[1, 2], [3, 4]])
# 1. 使用flatten()(独立数组)
flat_flatten = arr.flatten()
flat_flatten[0] = 99  # 修改展平数组
print("flatten修改后 - 展平数组:", flat_flatten)  # [99  2  3  4]
print("flatten修改后 - 原数组:\n", arr)  # [[1 2],[3 4]] → 原数组不变
# 2. 使用reshape(-1)(共享内存)
flat_reshape = arr.reshape(-1)
flat_reshape[0] = 99  # 修改展平数组
print("\nreshape修改后 - 展平数组:", flat_reshape)  # [99  2  3  4]
print("reshape修改后 - 原数组:\n", arr)  # [[99 2],[3 4]] → 原数组同步修改

这个例子把区别说得非常清楚。用 flatten() 时,你改的是副本,原数组没事;用 reshape(-1) 时,你改的是同一个东西,原数组也会跟着变。

为了方便记忆,有个简单的规则:需要独立的数据副本,就用 flatten();追求速度与内存效率,就用 reshape(-1)

五、适用场景(该用 flatten 还是 reshape?)

场景 1:优先用 flatten() 的情况

  • 需要保留原数组不变,避免修改展平数组影响原数据时
  • 展平后要对数据做大量修改,且不想污染原始数据时
# 原始温度数据(二维)
temp_2d = np.random.normal(5, 6, (31, 24)).round(1)
# 展平为一维用于统计,且不修改原数据
temp_flat = temp_2d.flatten()
temp_flat[0] = 0  # 仅修改拷贝,原数据不受影响
print("原数据第一值:", temp_2d[0,0])  # 仍为原始温度值

这个例子很典型。在做数据分析时,我们经常想对数据做各种变换,但又不想破坏原始数据集。这时候 flatten() 就是理想选择——给你的是一份安全的拷贝。

场景 2:优先用 reshape(-1) 的情况

  • 只是临时需要展平数组来计算个总和、均值,展平后的结果用完就扔
  • 处理大规模数据(比如百万、千万级元素),对速度和内存效率有要求
# 大规模数据(10万行×10列)
big_arr = np.random.rand(100000, 10)
# 快速展平计算总和(无需拷贝,速度快)
total = big_arr.reshape(-1).sum()
print("总和:", total)

看到没?如果只是算个总和,用 reshape(-1) 就足够了,速度快、省内存。用 flatten() 反而多拷贝一份数据,完全没必要。

六、进阶用法:高维数组展平 + 指定顺序

在实际应用中,我们经常需要处理高维数组。比如图像数据通常是 4 维的:批量大小 × 高度 × 宽度 × 通道数。通过 order 参数,我们可以控制展平的顺序,适应不同的业务需求。

import numpy as np
# 4维数组:2张图片 × 32行 × 32列 × 3通道(RGB)
img_arr = np.random.randint(0, 255, (2, 32, 32, 3))
print("原始4维数组形状:", img_arr.shape)  # (2, 32, 32, 3)
# 按行优先展平(默认)
img_flat_c = img_arr.flatten(order='C')
print("C风格展平形状:", img_flat_c.shape)  # (6144,) → 2×32×32×3=6144
# 按列优先展平
img_flat_f = img_arr.flatten(order='F')
print("F风格展平形状:", img_flat_f.shape)  # (6144,)

可以看到,即使面对 4 维数组,flatten() 也能轻松处理,而且通过 order 参数,我们完全可以控制元素读出的顺序——这在某些特定算法中可能会派上用场。

七、避坑点与常见问题

1. 常见误区

最常见的坑主要有三个:

  • ❌ 以为 flatten() 是 NumPy 全局函数:不对,它是数组对象的方法。如果你写 np.flatten(arr),会报错。必须写成 arr.flatten()
  • ❌ 混淆 flatten()ra vel()ra vel() 是 NumPy 函数,效果跟 reshape(-1) 类似,返回的是视图、共享内存;而 flatten() 返回的是拷贝。
  • ❌ 展平后修改原数组:如果用 flatten(),修改展平数组不会影响原数组;反过来,修改原数组也不会影响展平后那份拷贝。它们是互不干扰的“两个世界”。

2. 报错场景

还有一个很常见的问题:对普通 Python 列表直接使用 flatten()。列表没有这个方法,会直接抛出 AttributeError

# 错误:list.flatten()
# lst = [[1,2],[3,4]]
# lst.flatten() → AttributeError
# 正确做法:先转NumPy数组
lst = [[1,2],[3,4]]
arr = np.array(lst)
arr.flatten()  # [1 2 3 4]

先转成 NumPy 的 ndarray,再调用 flatten(),这步不能省。

总结

现在,做个小小的总结:

  1. flatten() 的核心功能:把任意维度的数组展平成一维,返回一个独立的拷贝,修改它不会影响原数组。
  2. 关键参数 order'C'(行优先,默认)和 'F'(列优先),控制展平的读取顺序。
  3. 与 reshape(-1) 的本质区别flatten() 是拷贝,独立内存;reshape(-1) 是视图,共享内存。
  4. 选型原则:需要独立数据、保护原数组 → 用 flatten();追求效率、临时计算 → 用 reshape(-1)
  5. 避坑关键flatten() 只能用于 NumPy 数组,普通列表先转成 ndarray。
本文转载于:https://www.jb51.net/python/36236669x.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注