Pandas DataFrame变形:将Movie_type转为列名、月份转为行值的实现
问题描述
我刚学习Python,想要实现类似R语言中的数据框变形操作。目前我有结构为d1的DataFrame,需要转换为d2的结构:
d1的列包含:Country、Movie_type(取值为Action、Romance或Drama),以及Jan-20、Feb-20、Mar-20三个月份列。
d2的列需要包含:Country、Month-Year(取值为Jan-20、Feb-20或Mar-20),以及Action、Drama、Romance三类电影类型列(注:示例d2中仅Action列取值对应d1真实计数,Drama和Romance列未填充真实值)。
示例数据代码如下:
d1 = pd.DataFrame({ "Country" : {0: "Australia",1: "Australia", 2:"Australia", 3:"Canada", 4:"Canada", 5:"Israel", 6:"India",7: "India", 8:"Poland", 9: "Zambia"}, "Movie_type" : {0: "Action",1:"Drama",2: "Romance",3: "Romance",4: "Action",5: "Action",6: "Action",7: "Drama",8: "Drama",9:"Action"}, "Jan-20" :{0: 0,1: 1,2: 2,3: 3,4: 0,5: 3,6: 2,7: 0,8: 2,9: 5}, "Feb-20" :{0: 2,1: 3,2: 2,3: 1,4: 0,5: 0,6: 2,7: 4,8: 2,9: 7}, "Mar-20" :{0: 1,1: 5,2: 2,3: 7,4: 4,5: 8,6: 2,7: 4,8: 5,9: 9} }) d2 = pd.DataFrame({ "Country" : {0: "Australia",1: "Australia", 2:"Australia", 3:"Canada", 4:"Canada", 5:"Canada", 6:"Israel",7: "Israel", 8:"Israel", 9: "India", 10: "India", 11: "India", 12: "Poland", 13: "Poland", 14: "Poland", 15: "Zambia", 16: "Zambia", 17: "Zambia"}, "Month_year" : {0: "Jan-20",1: "Feb-20", 2:"Mar-20", 3: "Jan-20",4: "Feb-20", 5:"Mar-20",6: "Jan-20",7: "Feb-20", 8:"Mar-20",9: "Jan-20",10: "Feb-20", 11:"Mar-20",12: "Jan-20",13: "Feb-20", 14:"Mar-20",15: "Jan-20",16: "Feb-20", 17:"Mar-20"}, "Action" :{0: 0,1: 0,2: 0,3: 0,4: 0,5: 0,6: 3,7: 0,8: 0,9: 2,10:0,11:0,12:0,13:0,14:0,15:5,16:0,17:0}, "Drama" :{0: 0,1: 0,2: 0,3: 0,4: 0,5: 0,6: 0,7: 0,8: 0,9: 0,10:0,11:0,12:0,13:0,14:0,15:0,16:0,17:0}, "Romance" :{0: 0,1: 0,2: 0,3: 0,4: 0,5: 0,6: 0,7: 0,8: 0,9: 0,10:0,11:0,12:0,13:0,14:0,15:0,16:0,17:0} })
问题:如何实现将Movie_type的取值转为列名、原d1中MMM-YY格式的列名转为行值的需求?该需求属于stack/unstack/pivot中的哪类变形操作?
实现代码
你可以通过melt+pivot两步组合操作实现需求,最终生成的d2会自动填充所有电影类型的真实计数:
# 第一步:将月份列从列名转为行值(列转行) d1_melt = d1.melt( id_vars=["Country", "Movie_type"], # 保持不动的标识列 var_name="Month_year", # 存储原月份列名的新列名 value_name="count" # 存储原月份列对应值的新列名 ) # 第二步:将Movie_type的取值转为列名(行转列) d2 = d1_melt.pivot( index=["Country", "Month_year"], # 作为结果行标识的列 columns="Movie_type", # 要转为列名的字段 values="count" # 填充到新列中的数值 ).reset_index().rename_axis(columns=None) # 重置索引、清除多余的columns名称 # 可选:将缺失值填充为0,转为整数类型匹配示例格式 d2 = d2.fillna(0).astype({"Action": int, "Drama": int, "Romance": int})
操作类型说明
- 第一步
melt属于**unpivot(列转行)**范畴,对应stack操作的反向逻辑:把原本分散在不同列的月份数据,收拢为同一列的不同行值 - 第二步
pivot属于**pivot(行转列)**范畴,对应unstack操作的逻辑:把原本同一列的不同电影类型取值,展开为不同的列 - 该需求属于组合变形操作,需要先将维度之一的月份从列转成行,再将另一个维度的电影类型从行转成列,才能得到目标结构。
内容的提问来源于stack exchange,提问作者Alice Sult
相关产品推荐
相关产品推荐

