如何在循环中追加合并所有DataFrame输出为单个DataFrame
问题本质
原有代码存在两个核心问题:
- 循环内每次执行
dfinal_p6 = ...赋值操作时,会直接覆盖该变量上一轮存储的内容,循环全程没有对每轮生成的单地块结果做持久化存储,最终变量只会保留最后一轮循环(id=50)的计算结果 - 缺失循环变量
foreign的自增逻辑,直接运行会触发死循环,程序永远停留在id=1的请求状态
实现方法
性能最优的实现逻辑如下:
- 在循环外部初始化一个空列表,用于暂存每轮处理完成的单地块DataFrame
- 每轮循环处理完单个地块的数据后,将结果追加到上述列表中,同时完成循环变量自增
- 所有地块请求、处理完成后,调用
pd.concat()一次性将列表内所有DataFrame合并为单个完整数据集
这种方式避免了循环内逐次拼接DataFrame产生的额外性能开销,运行效率远高于循环内逐次追加的写法。
修正后可直接运行的代码
import requests import pandas as pd # 初始化结果暂存列表 result_list = [] foreign_id = 1 while foreign_id <= 50: # 初始化基础请求地址 s1_base_url = 'https://demodev2.kappazeta.ee/ard_api_demo/v1/time_series/s1?limit_to_rasters=true&parcel_foreign_id=0&properties=parcel_foreign_id%2Cs1product_end_time%2Cs1product_ron%2Ccohvh_avg%2Ccohvv_avg%2Cvhvv_avg' s2_base_url = 'https://demodev2.kappazeta.ee/ard_api_demo/v1/time_series/s2?limit_to_rasters=true&parcel_foreign_id=0&properties=parcel_foreign_id%2Cs2product_start_time%2Cs2product_ron%2Cndvi_avg' url_param_pos = 101 id_str = str(foreign_id) # 替换地址中的地块id参数 s1_url = s1_base_url[:url_param_pos] + id_str + s1_base_url[url_param_pos+1:] s2_url = s2_base_url[:url_param_pos] + id_str + s2_base_url[url_param_pos+1:] # 发起接口请求 s1_resp = requests.get(s1_url) s2_resp = requests.get(s2_url) s1_data = s1_resp.json() s2_data = s2_resp.json() # 单地块数据格式化与合并 df_s1 = pd.DataFrame(s1_data['s1_time_series']) df_s2 = pd.DataFrame(s2_data['s2_time_series']) df_s2['s2product_start_time'] = df_s2['s2product_start_time'].str[0:11] df_s1['s1product_end_time'] = df_s1['s1product_end_time'].str[0:11] df_single_parcel = df_s1.merge( df_s2, how='inner', left_on='s1product_end_time', right_on='s2product_start_time' ) # 数值类型转换 num_cols = ['parcel_foreign_id_x', 's1product_ron', 'parcel_foreign_id_y', 's2product_ron'] df_single_parcel[num_cols] = df_single_parcel[num_cols].apply(pd.to_numeric, errors='coerce', axis=1) # 将当前地块结果存入暂存列表 result_list.append(df_single_parcel) # 循环变量自增,避免死循环 foreign_id += 1 # 一次性合并所有地块数据,重置行索引 final_df = pd.concat(result_list, ignore_index=True)
额外说明
- 禁止在循环内反复执行
final_df = pd.concat([final_df, df_single])这类操作,pandas每次合并都会生成全新的DataFrame对象,数据量较大时会产生严重的性能损耗 pd.concat()传入ignore_index=True参数可以自动生成连续的行索引,避免合并后出现重复的索引值- 修正代码对原冗余变量名做了简化,不影响原有数据处理逻辑,可读性更高
内容的提问来源于stack exchange,提问作者Abdullah
相关产品推荐
相关产品推荐

