Pandas合并多DataFrame报错:如何将字符串列表转为对象列表
问题原因
你之前的循环生成的是存储DataFrame变量名的字符串列表,不是实际的DataFrame对象,传给pd.merge时自然会触发类型错误。
解决方法
方法1:通过作用域字典直接取对应变量
Python会把当前作用域的所有变量存在字典里:全局作用域的变量存在globals()返回的字典中,函数内部的局部变量存在locals()返回的字典中,字典的key就是变量名的字符串,value就是变量本身。你只要按名字从字典里取值,就能拿到对应的DataFrame,不用硬编码把所有变量列一遍。
如果你的10个DataFrame是写在脚本、Jupyter单元格顶层的全局变量,直接用下面的代码构建列表就行:
from functools import reduce import pandas as pd offers_df_list = [] for i in range(1, 11): df_name = f'offer_{i}_activity' offers_df_list.append(globals()[df_name]) # 你原来写的合并逻辑不用改 offers_activity = reduce( lambda left, right: pd.merge(left, right, on='customer_id', how='outer'), offers_df_list )
如果这些DataFrame是定义在某个函数里的局部变量,把上面代码里的globals()换成locals()就能正常取到值。
别用
eval()做这个事,它有代码注入风险,要是变量名来源不可控很容易出安全问题,直接访问作用域字典稳妥得多。
方法2:从源头避免找变量的麻烦(推荐)
最规范的写法是你最开始生成这10个DataFrame的时候,就直接往列表里存,不要一个个单独命名成offer_1_activity、offer_2_activity这类分散的变量,后面根本不需要做「字符串转变量」的操作:
from functools import reduce import pandas as pd offers_df_list = [] for i in range(1, 11): # 这里替换成你原来生成每个活动DataFrame的逻辑,比如读csv、做数据统计之类的 # 举个例子:current_df = pd.read_csv(f'offer_{i}_activity_data.csv') current_df = # 你自己的df生成逻辑 offers_df_list.append(current_df) # 直接合并就行 offers_activity = reduce( lambda left, right: pd.merge(left, right, on='customer_id', how='outer'), offers_df_list )
踩坑提醒
用globals()/locals()取值的时候如果报KeyError,先检查对应序号的DataFrame是不是真的定义了,有没有拼错变量名,比如漏写下划线、序号写错这类低级问题。
内容的提问来源于stack exchange,提问作者minato namikaze
相关产品推荐
相关产品推荐

