Pandas技术问题:基于列值的动态窗口大小跨窗计算
嘿,我来帮你搞定这个基于列值的动态窗口计算问题!先把你的数据整理成可复现的Pandas DataFrame,方便后续操作:
import pandas as pd # 整理数据并处理缺失值(最后一行的经度和geohash缺失,先移除) data = { 'INDEX': [363446, 363428, 363425, 363411, 363406, 363401], 'DATETIME': ['2015-02-28 16:00:44.837', '2015-02-28 16:26:30.047', '2015-02-28 16:30:02.659', '2015-02-28 16:45:17.706', '2015-02-28 16:54:50.763', '2015-02-28 17:01:21.800'], 'LATITUDE': [41.712755, 41.434128, 41.421538, 41.377853, 41.290409, 41.295870], 'LONGITUDE': [-87.614916, -87.505173, -87.480122, -87.470677, -87.467947, None], 'GEOHASH': ['dp3tq38', 'dp3g8yb', 'dp3g9kd', 'dp3g3s9', 'dp3fcse', None] } df = pd.DataFrame(data) # 把时间戳转成Pandas可识别的datetime类型 df['DATETIME'] = pd.to_datetime(df['DATETIME']) # 移除缺失关键字段的行 df = df.dropna(subset=['LONGITUDE', 'GEOHASH']).reset_index(drop=True)
第一步:基于GEOHASH分组的动态时间窗口计算
结合你的数据,最常见的场景是按GEOHASH(同一地理区域)分组,然后在每个组内根据时间戳做动态时间窗口计算(比如统计每个时间点前N分钟内的位置均值)。
比如,我们要统计每个GEOHASH组内,每个时间点前10分钟窗口内的平均经纬度和点的数量:
# 先按地理哈希和时间排序,确保窗口计算顺序正确 df_sorted = df.sort_values(['GEOHASH', 'DATETIME']).set_index('DATETIME') # 定义动态时间窗口:每个点前10分钟的区间(左闭右开) dynamic_time_window = pd.Grouper(freq='10T', closed='left', label='right') # 分组后执行窗口聚合计算 window_stats = df_sorted.groupby(['GEOHASH', dynamic_time_window]).agg( avg_latitude=('LATITUDE', 'mean'), avg_longitude=('LONGITUDE', 'mean'), total_points=('LATITUDE', 'count') ).reset_index() print(window_stats)
第二步:自定义动态窗口大小(按组调整)
如果你的窗口大小需要根据列值动态变化(比如每个GEOHASH组的窗口大小由组内数据量决定),可以用groupby.apply自定义逻辑:
def calc_dynamic_window(group): # 假设窗口大小为组内数据量的1/2(向下取整,至少为1) window_size = max(1, len(group) // 2) # 计算每个点的滑动窗口均值 group['rolling_avg_lat'] = group['LATITUDE'].rolling(window=window_size, min_periods=1).mean() group['rolling_avg_lon'] = group['LONGITUDE'].rolling(window=window_size, min_periods=1).mean() return group # 按GEOHASH分组后应用自定义函数 dynamic_window_result = df_sorted.groupby('GEOHASH').apply(calc_dynamic_window).reset_index() print(dynamic_window_result[['DATETIME', 'GEOHASH', 'LATITUDE', 'rolling_avg_lat']])
扩展:空间维度的动态窗口计算
如果你的需求是基于空间距离的动态窗口(比如每个点周围X公里内的所有点,不管GEOHASH),可以用GeoPandas结合空间索引来实现:
import geopandas as gpd from shapely.geometry import Point # 转换为GeoDataFrame,便于空间计算 gdf = gpd.GeoDataFrame( df, geometry=gpd.points_from_xy(df.LONGITUDE, df.LATITUDE), crs="EPSG:4326" # WGS84坐标系 ) # 转换为以米为单位的投影坐标系,方便计算距离 gdf = gdf.to_crs("EPSG:3857") # 构建空间索引,提升查询效率 spatial_index = gdf.sindex # 自定义函数:计算每个点周围1000米内的平均经纬度 def spatial_window_calc(row): # 创建1000米缓冲区,获取可能的候选点 buffer = row.geometry.buffer(1000) candidate_indices = list(spatial_index.intersection(buffer.bounds)) candidates = gdf.iloc[candidate_indices] # 筛选出真正在1000米范围内的点 nearby_points = candidates[candidates.distance(row.geometry) <= 1000] return pd.Series({ 'nearby_avg_lat': nearby_points['LATITUDE'].mean(), 'nearby_avg_lon': nearby_points['LONGITUDE'].mean(), 'nearby_point_count': len(nearby_points) }) # 应用到每个行 spatial_result = gdf.apply(spatial_window_calc, axis=1) final_df = pd.concat([df, spatial_result], axis=1) print(final_df[['DATETIME', 'LATITUDE', 'LONGITUDE', 'nearby_avg_lat', 'nearby_point_count']])
内容的提问来源于stack exchange,提问作者user9506339
相关产品推荐
相关产品推荐

