基于DataFrame唯一列值创建列并填充经纬度数据
Pandas高效重塑DataFrame:将ID转为列并合并经纬度列表
嘿,我明白你想要的效果——把每个id转成列,对应单元格存[lat, long]的列表,还要按Timestamp分组,而且要避免低效的迭代对吧?这事儿用Pandas的内置方法就能轻松搞定,比循环快多了!
先看看你的原始数据:
import pandas as pd df = pd.DataFrame({ 'Timestamp': [665047, 665047, 2058714, 665348, 2055292], 'id': ['a', 'b', 'b', 'a', 'b'], 'lat': [30.508420, 30.491882, 30.492026, 30.508420, 30.491899], 'long': [-84.372882, -84.372938, -84.372938, -84.372882, -84.372938] })
你期望得到的结果是按Timestamp聚合,每个id作为列,值是经纬度列表:
Timestamp a b 0 665047 [30.508420, -84.372882] [30.491882, -84.372938] 1 665348 [30.508420, -84.372882] NaN 2 2055292 NaN [30.491899, -84.372938] 3 2058714 NaN [30.492026, -84.372938]
之前用iterrows()循环不仅代码麻烦,效率还低,尤其是当id有数千个的时候,循环肯定卡。这里给你两个高效的方法:
方法1:先合并经纬度为列表,再用pivot重塑
这个步骤很清晰,分两步走:
- 先给每行创建
[lat, long]的列表 - 用
pivot把id转成列,Timestamp作为索引
代码如下:
# 第一步:生成经纬度列表列 df['coords'] = df[['lat', 'long']].apply(list, axis=1) # 第二步:pivot重塑表格 result = df.pivot(index='Timestamp', columns='id', values='coords').reset_index() # 调整列名(去掉columns的层级) result.columns.name = None print(result)
运行结果正好是你想要的样子,而且完全用Pandas的矢量化操作,比循环快N倍,哪怕几千个id也能轻松处理。
方法2:用groupby+unstack一步到位
如果你想更简洁,可以用groupby按Timestamp和id分组,然后把每组的经纬度转成列表,再unstack把id转成列:
result = df.groupby(['Timestamp', 'id'])[['lat', 'long']] \ .apply(lambda x: x.values.tolist()[0]) \ .unstack('id') \ .reset_index() result.columns.name = None print(result)
这个方法和第一个效果一样,也是矢量化操作,效率同样很高。
为什么这两个方法比循环好?因为Pandas的内置方法都是用C实现的底层操作,避免了Python层面的循环开销,数据量越大,优势越明显。之前你的循环代码之所以没得到预期结果,是因为处理字典的时候逻辑没对齐,而用这些内置方法能直接精准实现需求。
内容的提问来源于stack exchange,提问作者user3483203
相关产品推荐
相关产品推荐

