Pandas中apply返回DataFrame的函数结果异常,如何修正?
问题分析与解决
问题重现
原代码如下:
import pandas as pd df = pd.DataFrame({'details': ['url1', 'url2', 'url3']}) def get_infos(x): if x == 'url1': return pd.DataFrame({'col1': ['aaa'], 'col2': ['bbb']}) elif x == 'url3': return pd.DataFrame({'col3': ['ccc'], 'col1': ['ddd']})
执行以下拼接代码后得到不符合预期的结果:
result = pd.concat([df, df['details'].apply(get_infos)], axis=1) print(result)
输出结果:
details details 0 url1 col1 col2 0 aaa bbb 1 url2 None 2 url3 col3 col1 0 ccc ddd
预期输出:
details col1 col2 col3 0 url1 aaa bbb NaN 1 url2 NaN NaN NaN 2 url3 ddd NaN ccc
问题原因
df['details'].apply(get_infos)返回的是一个Series对象,其中每个元素是小DataFrame或None:url1对应含col1/col2的DataFrame,url3对应含col3/col1的DataFrame,url2因函数未处理返回None。- 直接用
pd.concat(axis=1)拼接时,这个Series会被当作一列(列名仍为details,与原df的列重名),且每个单元格内嵌套了小DataFrame,导致输出结构混乱。 None值无法被解析为有效列,直接显示为单元格内容,而非填充NaN。
解决方案
核心思路是将apply返回的每个小DataFrame/None转换为单行Series,再与原df拼接,自动对齐列名并填充NaN。
方法一:在apply中转换为Series
import pandas as pd df = pd.DataFrame({'details': ['url1', 'url2', 'url3']}) def get_infos(x): if x == 'url1': return pd.DataFrame({'col1': ['aaa'], 'col2': ['bbb']}) elif x == 'url3': return pd.DataFrame({'col3': ['ccc'], 'col1': ['ddd']}) # 处理apply结果:将每个小DataFrame取第一行转成Series,None则返回空Series processed = df['details'].apply( lambda x: get_infos(x).iloc[0] if isinstance(get_infos(x), pd.DataFrame) else pd.Series() ) # 拼接原df和处理后的结果 result = pd.concat([df, processed], axis=1) print(result)
方法二:先合并所有小DataFrame再拼接
# 收集所有非None的结果,合并成一个DataFrame info_dfs = [] for url in df['details']: res = get_infos(url) info_dfs.append(res if isinstance(res, pd.DataFrame) else pd.DataFrame()) # 合并info_dfs,重置索引后与原df拼接 combined_info = pd.concat(info_dfs, ignore_index=True) result = pd.concat([df, combined_info], axis=1) print(result)
两种方法都能得到预期输出,自动对齐所有列名,缺失值填充为NaN。
内容的提问来源于stack exchange,提问作者VERBOSE
相关产品推荐
相关产品推荐

