循环生成的numpy数组如何作为列追加到Pandas DataFrame中
原有代码问题说明
原有代码无法运行的核心问题是pd.concat()仅支持拼接Pandas的Series、DataFrame对象,你向列表中存入的是普通Python列表,不属于Pandas可拼接对象,自然会抛出类型错误,且额外的数组转列表操作也增加了不必要的性能开销。
最优方案:一次性收集数组后构建DataFrame
该方案避免了循环中反复修改DataFrame的性能损耗(Pandas DataFrame为不可变结构,每次新增列都会全量复制数据,大数据量下性能极差),是效率最高的实现方式:
import pandas as pd import numpy as np import glob # 初始化容器存储所有列数组 col_arrays = [] for f in glob.glob(path + "/*.tif"): # 图像处理逻辑,输出一维numpy数组a,示例如下 a = np.array([1,2,3,4,5]) col_arrays.append(a) # 按列拼接所有数组后直接生成DataFrame df = pd.DataFrame(np.column_stack(col_arrays))
如果需要自定义列名(比如用文件名作为列标识),可以调整为:
col_arrays = [] col_names = [] for f in glob.glob(path + "/*.tif"): a = np.array([1,2,3,4,5]) col_arrays.append(a) # 提取文件名作为列名,可按需修改规则 col_names.append(f.split("/")[-1].replace(".tif", "")) df = pd.DataFrame(np.column_stack(col_arrays), columns=col_names)
循环逐列追加方案(仅适合小数据量场景)
如果确实需要在循环过程中实时追加列查看中间结果,可以用以下写法,但不推荐处理大量图像时使用:
# 初始化空DataFrame df = pd.DataFrame() for idx, f in enumerate(glob.glob(path + "/*.tif")): a = np.array([1,2,3,4,5]) # 直接将numpy数组赋值为新列,无需转列表 df[f"image_{idx}"] = a
注意事项
- 所有图像处理输出的numpy数组长度必须一致,否则构建DataFrame时会报错
- 示例代码中修正了原数组写法的语法问题,numpy数组元素间需要用逗号分隔
内容的提问来源于stack exchange,提问作者Jesh Kundem
相关产品推荐
相关产品推荐

