使用Pandas DataFrame写入数据时出现'append'属性不存在错误
问题:DataFrame调用append方法报错AttributeError
执行循环写入设备信息到DataFrame时,出现错误:
AttributeError: 'DataFrame' object has no attribute 'append'. Did you mean: '_append'?
可复现代码:
import pandas as pd import os import json currDir = os.getcwd() def parse_json_response(): filename = "my_json_file.json" device_name = ["Trona", "Sheldon"] "creating dataframe to store result" column_names = ["DEVICE", "STATUS", "LAST UPDATED"] result_df = pd.DataFrame(columns=column_names) my_json_file = currDir + '/' + filename for i in range(len(device_name)): my_device_name = device_name[i] with open(my_json_file) as f: data = json.load(f) for devices in data: device_types = devices['device_types'] if my_device_name in device_types['name']: if device_types['name'] == my_device_name: device = devices['device_types']['name'] last_updated = devices['devices']['last_status_update'] device_status = devices['devices']['status'] result_df = result_df.append( {'DEVICE': device, 'STATUS': device_status, 'LAST UPDATED': last_updated}, ignore_index=True) print(result_df) parse_json_response()
JSON文件内容(保存为当前路径下的my_json_file.json):
[{"devices": {"id": 34815, "last_status_update": "2023-05-25 07:56:49", "status": "idle" }, "device_types": {"name": "Trona"}}, {"devices": {"id": 34815, "last_status_update": "2023-05-25 07:56:49", "status": "idle" }, "device_types": {"name": "Sheldon"}}]
原因与解决方案
报错原因
Pandas 2.0及后续版本已正式移除DataFrame.append()方法,这是触发该错误的核心原因。
解决方案
推荐两种替代方式,同时优化原代码中的冗余操作:
方案1:改用pd.concat()合并DataFrame
将每次要添加的行转为单个DataFrame,再用pd.concat()合并到结果中:
import pandas as pd import os import json currDir = os.getcwd() def parse_json_response(): filename = "my_json_file.json" device_name = ["Trona", "Sheldon"] column_names = ["DEVICE", "STATUS", "LAST UPDATED"] result_df = pd.DataFrame(columns=column_names) my_json_file = os.path.join(currDir, filename) # 用os.path.join处理路径更安全 # 只读取一次JSON文件,避免循环重复IO操作 with open(my_json_file) as f: data = json.load(f) for my_device_name in device_name: # 直接遍历列表,无需通过索引取值 for devices in data: device_types = devices['device_types'] # 去掉重复判断,直接判断名称相等即可 if device_types['name'] == my_device_name: device = devices['device_types']['name'] last_updated = devices['devices']['last_status_update'] device_status = devices['devices']['status'] # 用pd.concat替代append new_row = pd.DataFrame([{'DEVICE': device, 'STATUS': device_status, 'LAST UPDATED': last_updated}]) result_df = pd.concat([result_df, new_row], ignore_index=True) print(result_df) parse_json_response()
方案2:先收集数据到列表,最后一次性生成DataFrame(效率更高)
这种方式避免多次合并DataFrame,性能更优,尤其数据量大时:
import pandas as pd import os import json currDir = os.getcwd() def parse_json_response(): filename = "my_json_file.json" device_name = ["Trona", "Sheldon"] column_names = ["DEVICE", "STATUS", "LAST UPDATED"] my_json_file = os.path.join(currDir, filename) data_list = [] # 用列表存储所有行数据 with open(my_json_file) as f: data = json.load(f) for my_device_name in device_name: for devices in data: device_types = devices['device_types'] if device_types['name'] == my_device_name: data_list.append({ 'DEVICE': devices['device_types']['name'], 'STATUS': devices['devices']['status'], 'LAST UPDATED': devices['devices']['last_status_update'] }) # 最后一次性生成DataFrame result_df = pd.DataFrame(data_list, columns=column_names) print(result_df) parse_json_response()
额外优化点
- 原代码在循环中重复读取JSON文件,改为只读取一次,减少IO开销
- 直接遍历
device_name列表,无需通过索引取值,代码更简洁 - 去掉了重复的
if my_device_name in device_types['name']判断,直接判断相等即可,逻辑更清晰
内容的提问来源于stack exchange,提问作者ilexcel
相关产品推荐
相关产品推荐

