Pandas:转置DataFrame并利用列名创建多级索引
将宽格式DataFrame转换为长格式(Count形式)
嘿,你想要把宽格式的DataFrame转成目标里的长格式表格对吧?其实不用绕弯子用df.T——虽然转置也能实现,但步骤会繁琐很多。Pandas专门提供了stack()和melt()这两个工具,直接就能搞定宽转长的需求,我给你一步步演示:
首先先还原你的原始DataFrame,方便你复现测试:
import pandas as pd # 构造原始数据 data = { 'user': ['Me', 'Myself', 'And_Irene'], '2019-01-01': [1.0, 2.0, 3.0], '2019-01-02': [3.0, 2.0, 1.0] } df = pd.DataFrame(data)
方法一:用stack()(推荐,适合索引式的宽转长)
这个方法的思路是把日期列"堆叠"成索引的一部分,再调整结构:
# 1. 把user列设置为DataFrame的索引 df_indexed = df.set_index('user') # 2. 调用stack(),将日期列名转为二级索引,数值转为单列 stacked_df = df_indexed.stack().reset_index() # 3. 给列重命名成你想要的名称 stacked_df.columns = ['user', 'Date', 'Count'] # 4. 调整列顺序,并设置Date和user为复合索引(和目标格式一致) final_result = stacked_df[['Date', 'user', 'Count']].set_index(['Date', 'user'])
运行后得到的结果就是你想要的:
Count Date user 2019-01-01 Me 1.0 Myself 2.0 And_Irene 3.0 2019-01-02 Me 3.0 Myself 2.0 And_Irene 1.0
方法二:用melt()(更直观,适合初学者)
melt()是专门为宽转长设计的函数,参数含义很清晰:
# id_vars:保留作为标识的列(这里是user) # var_name:原来的列名(日期)要转成的新列名 # value_name:原来的数值要转成的新列名 melted_df = df.melt(id_vars='user', var_name='Date', value_name='Count') # 同样调整列顺序和索引 final_result = melted_df[['Date', 'user', 'Count']].set_index(['Date', 'user'])
这个方法和stack()得到的结果完全一致,而且代码更简洁易懂。
如果你非要用df.T的话...
当然也能实现,但步骤会绕很多:
# 1. 先转置 df_transposed = df.T # 2. 把第一行(原来的user列值)设为新的列名 new_columns = df_transposed.iloc[0] df_transposed = df_transposed[1:] df_transposed.columns = new_columns # 3. 重置索引,再用melt转成长格式 result_t = df_transposed.reset_index().melt(id_vars='index', var_name='user', value_name='Count') # 4. 调整列名和顺序 result_t.columns = ['Date', 'user', 'Count'] final_result_t = result_t[['Date', 'user', 'Count']].set_index(['Date', 'user'])
你看,是不是比前面两种方法麻烦多了?所以还是优先用stack()或者melt()更高效~
内容的提问来源于stack exchange,提问作者Zizzipupp
相关产品推荐
相关产品推荐

