如何合并两个Pandas DataFrame的时间分组以同步迭代?
如何同步迭代两个按时间分组的DataFrame分组结果
我已经生成并按时间戳(每秒频率)完成分组的两个DataFrame:
import pandas as pd import numpy as np last5s = pd.Timestamp.now().replace(microsecond=0) - pd.Timedelta('5s') dates = pd.date_range(last5s, periods = 5, freq='s') N=10 data1 = np.random.randint(0,10,N) data2 = np.random.randint(0,10,N) df1 = pd.DataFrame({'timestamp': np.random.choice(dates, size=N), 'A': data1}) df2 = pd.DataFrame({'timestamp': np.random.choice(dates, size=N), 'B': data2}) # 执行分组 g1 = df1.groupby(pd.Grouper(key='timestamp', freq='1s')) g2 = df2.groupby(pd.Grouper(key='timestamp', freq='1s'))
分组后的输出示例如下:
timestamp A 0 2024-03-01 10:05:26 7 1 2024-03-01 10:05:25 8 2 2024-03-01 10:05:28 1 3 2024-03-01 10:05:24 2 4 2024-03-01 10:05:28 5 5 2024-03-01 10:05:27 4 6 2024-03-01 10:05:24 6 7 2024-03-01 10:05:26 3 8 2024-03-01 10:05:26 8 9 2024-03-01 10:05:28 8 timestamp B 0 2024-03-01 10:05:25 1 1 2024-03-01 10:05:26 6 2 2024-03-01 10:05:25 5 3 2024-03-01 10:05:28 7 4 2024-03-01 10:05:27 7 5 2024-03-01 10:05:28 1 6 2024-03-01 10:05:28 4 7 2024-03-01 10:05:25 0 8 2024-03-01 10:05:24 6 9 2024-03-01 10:05:24 5 g1: time: 2024-03-01 10:05:24 timestamp A 3 2024-03-01 10:05:24 2 6 2024-03-01 10:05:24 6 time: 2024-03-01 10:05:25 timestamp A 1 2024-03-01 10:05:25 8 time: 2024-03-01 10:05:26 timestamp A 0 2024-03-01 10:05:26 7 7 2024-03-01 10:05:26 3 8 2024-03-01 10:05:26 8 time: 2024-03-01 10:05:27 timestamp A 5 2024-03-01 10:05:27 4 time: 2024-03-01 10:05:28 timestamp A 2 2024-03-01 10:05:28 1 4 2024-03-01 10:05:28 5 9 2024-03-01 10:05:28 8 g2: time: 2024-03-01 10:05:24 timestamp B 8 2024-03-01 10:05:24 6 9 2024-03-01 10:05:24 5 time: 2024-03-01 10:05:25 timestamp B 0 2024-03-01 10:05:25 1 2 2024-03-01 10:05:25 5 7 2024-03-01 10:05:25 0 time: 2024-03-01 10:05:26 timestamp B 1 2024-03-01 10:05:26 6 time: 2024-03-01 10:05:27 timestamp B 4 2024-03-01 10:05:27 7 time: 2024-03-01 10:05:28 timestamp B 3 2024-03-01 10:05:28 7 5 2024-03-01 10:05:28 1 6 2024-03-01 10:05:28 4
现在需要实现同步迭代这两个分组,获取同一时间点对应的group1和group2,实现类似如下逻辑:
for time, group1, group2 in somehow_joined(g1,g2): # 对该共同时间组内的group1和group2执行操作
解决方案
方法1:将分组转为字典后按时间键迭代
把两个分组对象转换为以时间戳为键、分组DataFrame为值的字典,然后遍历所有时间键的并集,即可同步获取对应时间的两个分组:
# 将分组转为字典 g1_dict = dict(g1) g2_dict = dict(g2) # 获取所有时间点(包含两个分组的全部时间) all_times = set(g1_dict.keys()).union(set(g2_dict.keys())) # 按时间顺序同步迭代 for time in sorted(all_times): # 若某时间点仅存在于一个分组中,返回空DataFrame(可根据需求修改默认值) group1 = g1_dict.get(time, pd.DataFrame(columns=['timestamp', 'A'])) group2 = g2_dict.get(time, pd.DataFrame(columns=['timestamp', 'B'])) # 这里执行你的操作 print(f"=== 时间: {time} ===") print("group1:") print(group1) print("group2:") print(group2) print()
方法2:先合并原始DataFrame再分组
如果允许先合并原始数据,这是更简洁的实现方式:
# 按timestamp外连接合并两个DataFrame,保留所有时间点 merged_df = pd.merge(df1, df2, on='timestamp', how='outer') # 按每秒频率重新分组 g_merged = merged_df.groupby(pd.Grouper(key='timestamp', freq='1s')) # 迭代分组并拆分出原分组数据 for time, group in g_merged: # 过滤空值,还原group1和group2的结构 group1 = group[['timestamp', 'A']].dropna(subset=['A']).reset_index(drop=True) group2 = group[['timestamp', 'B']].dropna(subset=['B']).reset_index(drop=True) # 执行你的操作 print(f"=== 时间: {time} ===") print("group1:") print(group1) print("group2:") print(group2) print()
方法3:使用zip_longest同步迭代(适用于分组顺序一致的场景)
如果两个分组的时间顺序完全一致(比如均按时间升序排列),可以用itertools.zip_longest直接同步迭代:
from itertools import zip_longest for (time1, group1), (time2, group2) in zip_longest(g1, g2): # 确保时间匹配(若分组顺序完全一致可省略此判断) if time1 == time2: print(f"=== 时间: {time1} ===") print("group1:") print(group1) print("group2:") print(group2) print() else: # 处理时间不匹配的情况,根据需求调整逻辑 pass
注意:若两个分组的时间点或顺序存在差异,此方法可能出现时间不匹配的问题,需额外处理。
内容的提问来源于stack exchange,提问作者Ben Farmer
相关产品推荐
相关产品推荐

