如何通过转置将Pandas DataFrame转换为含-1缺失标记的矩阵
解决DataFrame转指定矩阵格式的问题
嘿,我来帮你把这个长格式的DataFrame转换成你需要的矩阵样式!咱们一步步用pandas来实现,逻辑清晰又好调整。
步骤1:加载示例数据
先把你给出的示例数据转换成DataFrame:
import pandas as pd data = { 'code': [101, 101, 102, 102, 102, 103, 103], 'y_m': ['2017-11', '2017-12', '2017-11', '2017-12', '2018-01', '2017-11', '2017-12'], 'count': [86, 32, 11, 34, 46, 56, 89] } df = pd.DataFrame(data)
步骤2:转成宽格式并处理缺失值
用pivot_table把y_m转成列,code作为行,count填充单元格,缺失的位置先留空,之后替换成占位符-1:
# 生成宽表,聚合方式用sum确保唯一值对应 wide_df = df.pivot_table(index='code', columns='y_m', values='count', aggfunc='sum') # 把空值替换成指定占位符-1 wide_df = wide_df.fillna(-1)
这一步得到的中间结果是:
| code | 2017-11 | 2017-12 | 2018-01 |
|---|---|---|---|
| 101 | 86 | 32 | -1 |
| 102 | 11 | 34 | 46 |
| 103 | 56 | 89 | -1 |
步骤3:添加合计行与合计列
接下来要补充每个code的行合计、每个月份的列合计,注意计算时要把-1当成缺失值排除:
# 计算每个code的合计(跳过-1) wide_df['total'] = wide_df.apply(lambda row: sum(x for x in row if x != -1), axis=1) # 计算每个月份的合计(跳过-1) month_total = wide_df.drop('total', axis=1).apply(lambda col: sum(x for x in col if x != -1), axis=0) # 补充总合计,把月份合计转成一行加到宽表顶部 month_total['total'] = month_total.sum() wide_df = pd.concat([pd.DataFrame(month_total).T, wide_df]) # 重置索引方便后续调整 wide_df = wide_df.reset_index()
步骤4:调整成目标矩阵格式
最后调整索引和列名,匹配你要的样式:
# 构造新的列名和索引序列 new_cols = [-1, 0] + list(wide_df.columns[1:-1]) new_index = [0, 1] + list(range(2, len(wide_df))) # 插入新索引列,重命名所有列 wide_df.insert(0, 'new_index', new_index) wide_df.columns = new_cols # 修正左上角的特殊值 wide_df.iloc[0, 0] = -1 wide_df.iloc[0, 1] = 0 # 修正第二行的索引和合计值 wide_df.iloc[1, 0] = 0 # 修正code行的索引 wide_df.iloc[2:, 0] = wide_df.iloc[2:, 0].astype(int)
最终结果
运行完所有代码后,你就能得到和需求一致的矩阵:
-1 0 2017-11 2017-12 2018-01 0 -1 0 153 155 46 1 0 354 153 155 46 2 101 118 86 32 -1 3 102 91 11 34 46 4 103 145 56 89 -1
注:你给出的示例里103的2017-11写的是-1,应该是笔误,这里按原数据的56处理了,如果需要调整可以修改fillna的逻辑。
内容的提问来源于stack exchange,提问作者daiyue
相关产品推荐
相关产品推荐

