You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas for循环追加DataFrame行时如何用pd.concat替换df.append

问题背景

更新pandas版本后会收到如下弃用警告:

'The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.'

本次涉及的三个数据集结构如下:

  • b1:b波段滤光片观测的人造星数据,列包含 ['Id', 'x', 'y', 'bmag']
  • i1:I波段滤光片观测的人造星数据,列包含 ['Id', 'x', 'y', 'imag']
  • biart:实测星数据,列包含 ['Id', 'x', 'y', 'bmag', 'imag']

原代码逻辑:遍历b1中所有人造星,计算其与biart中实测星的最小径向距离,若最小距离≤0.5,则同时保留人造星与匹配到的实测星对应的Id、坐标、星等、距离字段。


直接替换append的pd.concat写法

df.append(单条记录字典, ignore_index=True)的本质是将字典转为单行表结构后,和原表做纵向拼接。替换时只需要先将待追加的字典转为单行DataFrame,再传入pd.concat即可,替换代码片段如下:

# 将待追加的字典放在列表中,转为单行DataFrame
new_row = pd.DataFrame([{
    'Id_art': b1['Id'].iloc[i],
    'x_art':b1['x'].iloc[i], 
    'y_art': b1['y'].iloc[i],
    'bmag_art':b1['bmag'].iloc[i],
    'imag_art':i1['imag'].iloc[i],
    'dist_d':min(dist),
    'Id_meas':biart['Id'].iloc[dist.idxmin()], 
    'x_meas':biart['x'].iloc[dist.idxmin()],
    'y_meas':biart['y'].iloc[dist.idxmin()], 
    'bmag_meas':biart['bmag'].iloc[dist.idxmin()],
    'imag_meas':biart['imag'].iloc[dist.idxmin()]
}])
# 拼接时传入待拼接对象组成的列表,ignore_index=True重置行索引
extract = pd.concat([extract, new_row], ignore_index=True)

注意:字典必须放在列表中再传入pd.DataFrame,否则字典键会被识别为列索引引发报错。


高性能改写方案(推荐)

逐行遍历+每次循环拼接DataFrame的写法效率极低,每次拼接操作都会全量复制整个DataFrame,数据量较大时运行速度会非常慢。更合理的实现方式是先把所有符合条件的记录存入普通列表,遍历完成后一次性转为DataFrame,完全不需要循环内做表拼接,性能可提升数十倍到数百倍,完整代码如下:

import numpy as np
import pandas as pd

# 预定义输出表的列顺序
output_cols = [
    'Id_art', 'x_art', 'y_art', 
    'bmag_art', 'imag_art', 'dist_d',
    'Id_meas', 'x_meas', 'y_meas',                                 
    'bmag_meas', 'imag_meas'
]
# 用普通列表存储符合条件的记录,避免循环内重复复制DataFrame
valid_records = []

for i in range(len(b1.index)):
    x_art = b1['x'].iloc[i]
    y_art = b1['y'].iloc[i]
    
    # 计算当前人造星到所有实测星的距离
    dist_arr = np.sqrt((x_art - biart['x'])**2 + (y_art - biart['y'])**2)
    min_dist = dist_arr.min()
    
    # 距离满足阈值才保留记录
    if min_dist <= 0.5:
        match_idx = dist_arr.idxmin()
        # 组装当前匹配对的记录
        curr_record = [
            b1['Id'].iloc[i],
            x_art,
            y_art,
            b1['bmag'].iloc[i],
            i1['imag'].iloc[i],
            min_dist,
            biart['Id'].iloc[match_idx],
            biart['x'].iloc[match_idx],
            biart['y'].iloc[match_idx],
            biart['bmag'].iloc[match_idx],
            biart['imag'].iloc[match_idx]
        ]
        valid_records.append(curr_record)
        # 保留原有的打印逻辑
        print(*curr_record)

# 遍历结束后一次性生成最终结果表
extract = pd.DataFrame(valid_records, columns=output_cols)

该写法完全规避了append弃用问题,同时运行效率远高于逐行拼接的实现。


内容的提问来源于stack exchange,提问作者mmfranco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:30:54