向Pandas DataFrame追加元组报cannot concatenate错误如何解决
问题原因
你的代码存在两个直接触发报错的问题,还有一个明显的性能隐患:
- 核心报错原因:
pandas.DataFrame.append()仅支持接收Series、DataFrame、带键值映射的字典作为待拼接对象,不支持直接传入无字段信息的裸元组/列表。你传入的元组包含字符串类型值时,pandas无法自动将元组内的值和预设的A/B/C/D列做匹配,就会抛出TypeError: cannot concatenate object of type '<class 'str'>'; only Series and DataFrame objs are valid错误。 - 语法疏漏:循环语句
for i in range:本身写法不合法,range是Python内置类,必须传入整数参数生成可迭代的range对象(比如range(len(x)))才能用于循环遍历。 - 性能问题:逐行调用
append拼接DataFrame是极低效的写法,每次调用都会完整复制整个DataFrame生成新对象,数据量超过千行时运行速度会明显变慢;且pandas 1.4.0及以上版本已经正式废弃append接口,后续版本会直接移除该方法,不建议继续使用。
修正方案
根据你的使用场景选对应写法即可:
方案1:小数据量快速兼容(适配旧版pandas)
把裸元组改成和列名对应的字典,补全循环参数,追加时加上ignore_index=True避免索引重复:
import pandas as pd df = pd.DataFrame(columns=['A','B','C','D']) # 传入源数据长度生成可迭代对象 for i in range(len(x)): # 构造列名和值一一映射的字典 row = { 'A': x['col1'][i], 'B': x['col2'][i], 'C': x['col3'][i], 'D': x['col4'][i] } df = df.append(row, ignore_index=True)
方案2:官方推荐高性能写法(兼容所有新版pandas)
不要在循环里逐行拼接,先把所有行数据存到普通列表里,循环结束后一次性生成DataFrame,运行速度比逐行append高几十到上百倍:
import pandas as pd row_cache = [] # 遍历源数据,把每行结果先存在列表里 for i in range(len(x)): single_row = ( x['col1'][i], x['col2'][i], x['col3'][i], x['col4'][i] ) row_cache.append(single_row) # 一次性生成DataFrame,指定列名即可 df = pd.DataFrame(row_cache, columns=['A','B','C','D'])
如果你的源数据x本身就是pandas DataFrame结构,不需要写循环,直接做列选取和重命名就能拿到结果,性能最优:
df = x[['col1', 'col2', 'col3', 'col4']].rename(columns={ 'col1': 'A', 'col2': 'B', 'col3': 'C', 'col4': 'D' }).reset_index(drop=True)
内容的提问来源于stack exchange,提问作者Marcelo Soares
相关产品推荐
相关产品推荐

