如何合并含列表列的Pandas DataFrame,保留最近时间戳的列表内容?
合并时间序列DataFrame并累加食物列表
问题背景
有两个以time为索引的DataFrame A和B,分别记录不同类别的食物历史记录,需要合并所有时间点,每个时间点的food列表为A、B在该时间及之前最近的条目合并结果。已知两类食物无重叠,且A、B的时间戳不重叠。直接用pd.concat([A,B])无法实现需求,因为它仅堆叠行,不会处理历史累加和列表合并。
解决方案
核心思路是先为所有时间点补全A、B各自的最近历史记录,再合并对应列表:
1. 构造示例数据
首先还原问题中的DataFrame:
import pandas as pd # 构造DataFrame A data_a = {'food': [["apple","orange"], ["apple","orange","banana"]]} A = pd.DataFrame(data_a, index=pd.to_datetime(["2021-08-20", "2021-08-28"])) # 构造DataFrame B data_b = {'food': [["squash"], ["squash","carrot"], ["carrot"]]} B = pd.DataFrame(data_b, index=pd.to_datetime(["2021-08-19", "2021-08-24", "2021-08-29"]))
2. 生成完整时间索引
合并A、B的所有时间戳并排序,得到需要处理的全部时间点:
all_times = A.index.union(B.index).sort_values()
3. 向前填充补全历史记录
对A、B分别重新索引到完整时间序列,并用ffill()(向前填充)补全每个时间点对应的最近历史食物列表:
# 补全A的历史记录:每个时间点取之前最近的食物列表 A_filled = A.reindex(all_times).ffill() # 补全B的历史记录 B_filled = B.reindex(all_times).ffill()
4. 合并食物列表
由于已知两类食物无重叠,直接将对应行的列表相加即可得到该时间点的全部食物:
result = pd.DataFrame( A_filled['food'] + B_filled['food'], index=all_times, columns=['food'] )
最终输出
打印result即可得到期望的结果:
food 2021-08-19 [squash] 2021-08-20 [apple, orange, squash] 2021-08-24 [apple, orange, squash, carrot] 2021-08-28 [apple, orange, banana, squash, carrot] 2021-08-29 [apple, orange, banana, carrot]
原理说明
reindex:将DataFrame对齐到完整时间索引,缺失的时间点会填充NaN;ffill():用前一个非NaN的值填充当前NaN,确保每个时间点都能拿到A、B各自最新的历史记录;- 列表相加:因为两类食物无重叠,直接拼接即可得到全部食物,无需去重。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

