Pandas中apply生成DataFrame后,为何concat两种写法效果不同?
先明确testapply的本质:它是一个pandas Series,这个Series的每一个元素都是你自定义函数返回的独立DataFrame对象。
为什么第一种写法可行?
pd.concat([testapply[0],testapply[1],testapply[2],testapply[3]])
这里你手动把Series里的4个DataFrame元素提取出来,放进了一个列表。pd.concat的核心逻辑就是接收可迭代的DataFrame/Series集合,然后按指定轴(默认是行方向)拼接。这个列表里全是DataFrame,完全符合concat的预期输入,所以能正常拼接成一个大的DataFrame。
为什么第二种写法不行?
pd.concat([testapply])
这里你把整个Series对象放进列表传给concat,相当于让concat去拼接这个Series本身。但concat不会自动解析Series内部的DataFrame元素,它只会把这个Series当作普通拼接单元处理。最终得到的是一个以原Series为基础的结构(本质是带MultiIndex的DataFrame,每个单元格存的是原来的小DataFrame对象),完全不是你想要的拼接效果。
正确的简化写法
既然testapply本身就是存储DataFrame的可迭代对象(Series是可迭代的),直接把它传给concat就行:
pd.concat(testapply)
这样concat会自动遍历Series里的每个DataFrame元素,把它们按行拼接成大DataFrame,效果和第一种写法完全一致,还更简洁。
验证小技巧
你可以打印type(testapply),会看到输出是pandas.core.series.Series;再打印testapply.iloc[0],能直观看到这是一个DataFrame对象。对比两种concat写法的输出结果,就能清晰看到差异。
内容的提问来源于stack exchange,提问作者Wietze314

