Python Pandas:仅基于单个列进行重采样的问题
解决按15分钟重采样统计各站点自行车到达量的问题
嘿,我完全懂你的需求——你想要按15分钟的时间区间,统计每个站点的自行车到达次数,但目前的代码把站点信息错误聚合了,没法看到每个时间段里每个站点的具体数据(包括那些没有到达记录的站点)。我来帮你调整代码,实现你想要的输出结构。
先梳理你的问题核心
你有骑行数据,核心字段是end_station(到达站点)和dtm_end_trip(到达时间),期望输出是:
- 每15分钟一个时间区间
- 每个区间下,所有站点各占一行
count列对应该时间段内到达该站点的自行车数量(没有到达则为0)
你的现有代码问题分析
你当前的代码先按end_station和dtm_end_trip聚合计数,再重采样,这样会导致两个问题:
- 重采样时会把同一时间段的不同站点合并,丢失站点维度的信息
- 无法自动补全“该时间段内没有到达记录的站点”,导致这些站点的行直接缺失
解决方案代码
下面是调整后的代码,完全匹配你的期望输出:
import pandas as pd # 第一步:确保时间列是datetime类型(必须先做这个!) df['dtm_end_trip'] = pd.to_datetime(df['dtm_end_trip']) # 第二步:生成所有需要的时间区间和站点的完整组合(笛卡尔积) all_stations = df['end_station'].unique() # 获取所有唯一站点 # 生成从最早到达时间到最晚到达时间的15分钟间隔序列 time_intervals = pd.date_range( start=df['dtm_end_trip'].min().floor('15T'), # 向下取整到最近的15分钟 end=df['dtm_end_trip'].max().ceil('15T'), # 向上取整到最近的15分钟 freq='15T' ) # 创建时间区间和站点的全组合,确保每个时间段每个站点都有记录 full_combinations = pd.MultiIndex.from_product( [time_intervals, all_stations], names=['dtm_end_trip', 'end_station'] ).to_frame(index=False) # 第三步:对原始数据按15分钟+站点分组统计到达数 arrival_counts = df.groupby( [pd.Grouper(key='dtm_end_trip', freq='15T'), 'end_station'] ).size().reset_index(name='count') # 第四步:合并全组合和统计结果,填充缺失的count为0 final_result = pd.merge( full_combinations, arrival_counts, on=['dtm_end_trip', 'end_station'], how='left' ).fillna(0).astype({'count': int}) # 把count转成整数类型 # 可选:按时间和站点排序,让结果更规整 final_result = final_result.sort_values(['dtm_end_trip', 'end_station']).reset_index(drop=True) print(final_result)
代码逻辑解释
- 时间列格式校验:先把
dtm_end_trip转成datetime类型,这是时间重采样的基础 - 生成全组合:通过笛卡尔积创建“所有时间区间×所有站点”的完整列表,这是实现“每个时间段每个站点都有行”的关键
- 分组统计:用
pd.Grouper直接按15分钟对到达时间分组,同时按站点分组,得到每个时间段每个站点的真实到达数 - 合并填充:把统计结果和全组合合并,缺失的
count填充为0,完美匹配你的期望输出结构
示例输出效果
运行后你会得到类似这样的结果(和你给出的期望结构一致):
| dtm_end_trip | end_station | count |
|---|---|---|
| 2018-10-01 10:15:00 | A | 2 |
| 2018-10-01 10:15:00 | B | 0 |
| 2018-10-01 10:15:00 | C | 1 |
| 2018-10-01 10:15:00 | D | 2 |
| 2018-10-01 10:30:00 | A | 3 |
| 2018-10-01 10:30:00 | B | 2 |
内容的提问来源于stack exchange,提问作者user14738548
相关产品推荐
相关产品推荐

