如何将Pandas DataFrame按id列转换为宽格式时间序列表
嘿,这个需求其实用Pandas自带的工具就能轻松搞定,比你写循环高效多了!我来给你几个简洁的实现方式:
方法一:用pivot一步转宽表(最推荐)
pivot就是Pandas专门为长表转宽表设计的函数,完美匹配你的需求:
# 先把time列转成datetime类型(可选,但后续做时间操作更方便) df['time'] = pd.to_datetime(df['time']) # 直接生成宽格式,time作为索引,id作为列,value填充对应值 wide_df = df.pivot(index='time', columns='id', values='value')
运行后得到的结果就是你想要的:
id 100 200 300 time 2012-04-01 2.3 3.0 3.1 2012-04-02 3.4 2.9 4.2 2012-04-03 1.4 2.8 2.5 2012-04-04 5.6 1.9 1.2
方法二:用groupby + unstack(满足你想用groupby的需求)
如果你更倾向用groupby的思路,可以先按time和id分组,再把id从行索引“展开”成列:
df['time'] = pd.to_datetime(df['time']) wide_df = df.groupby(['time', 'id'])['value'].first().unstack('id')
这个方法和pivot效果完全一致,适合习惯分组操作的场景。
说说你之前代码的问题
你之前用pd.concat(list_dfs)得到重复索引的结果,是因为默认是按行拼接(axis=0),把每个id的时间序列堆在了一起。如果要让你的循环方法生效,只需要改成按列拼接:
list_dfs = [] for i in df['id'].unique(): list_dfs.append(df[df['id'] == i].set_index('time').drop('id', axis=1).rename(columns={'value':i})) # 加上axis=1,按列拼接并自动对齐索引 wide_df = pd.concat(list_dfs, axis=1)
不过这种循环的方式不如内置函数高效,数据量大的时候差距会很明显,还是推荐前面两种方法~
内容的提问来源于stack exchange,提问作者Euler_Salter
相关产品推荐
相关产品推荐

