如何转置不规则二维数组(锯齿状数组)

14次阅读

如何转置不规则二维数组(锯齿状数组)

numpy 中无法直接对不规则(行长度不同)的二维数组进行标准转置,但可通过 `itertools.zip_longest` 配合列表推导式实现安全、灵活的转置,并自动剔除填充的 `none` 值。

对于锯齿状(jagged)二维数组——即各行元素数量不一致的嵌套列表或 dtype=Object 的 NumPy 数组——传统 .T 或 np.transpose() 会报错或行为异常,因为其底层依赖矩形内存布局。此时需采用基于 python 迭代协议的通用方案。

核心思路是:将每行视为一个可迭代对象,用 zip_longest(*seats) 按列“拉链式”聚合元素。该函数会在较短行末尾补 None,确保所有列长度一致;随后通过列表推导式过滤掉 None,得到真正有效的转置结果。

以下为完整可运行示例:

import numpy as np from itertools import zip_longest  seats = np.Array([     [1, 2, 3, 4, 5],     [1, 2, 3, 4],     [1, 2, 3],     [1, 2, 3, 4],     [1, 2],     [1, 2] ], dtype=object)  # 步骤 1:使用 zip_longest 实现“补齐式”列聚合 padded_columns = list(zip_longest(*seats)) # 输出示例:[(1,1,1,1,1,1), (2,2,2,2,2,2), (3,3,3,3,None,None), ...]  # 步骤 2:过滤 None,生成纯净转置列表 transposed_seats = [list(filter(lambda x: x is not None, col)) for col in padded_columns] # 或更简洁写法(推荐): # transposed_seats = [[x for x in col if x is not None] for col in padded_columns]  print(transposed_seats) # [[1, 1, 1, 1, 1, 1],  #  [2, 2, 2, 2, 2, 2],  #  [3, 3, 3, 3],  #  [4, 4, 4],  #  [5]]

⚠️ 注意事项:

  • 若原始数据中本身可能包含 None 值,应改用自定义 fillvalue(如 fillvalue=object())并用 is 判断,避免误删有效 None;
  • 结果为 Python 列表嵌套结构,如需转为 dtype=object 的 NumPy 数组,可执行 np.array(transposed_seats, dtype=object);
  • 该方法时间复杂度为 O(N),其中 N 为所有元素总数,适用于中等规模数据;超大规模场景建议预统计最大列长后手动索引构造,以减少动态判断开销。

总结:锯齿数组转置本质是“按列收集非空元素”,zip_longest 提供了最直观、健壮且无需外部依赖的解决方案,是处理不规则结构的标准实践。

text=ZqhQzanResources