解析多层索引Pandas DataFrame并转换为元组列表
解析多层索引Pandas DataFrame并转换为元组列表
问题/任务
我需要写一个函数,输入是如图1所示的Pandas DataFrame(以Markdown表格呈现),将它转换输出成指定结构的列表。期待大家的反馈和帮助!
Fig 1: Pandas Data Frame (Function Input) as Markdown
| resources | ('Widget A (idx = 0)', 't1') | ('Widget A (idx = 0)', 't2') | ('Widget A (idx = 0)', 't3') | ('Widget A (idx = 0)', 't4') | ('Widget A (idx = 0)', 't5') | ('Widget A (idx = 0)', 't6') | ('Widget A (idx = 0)', 't7') | ('Widget A (idx = 0)', 't8') | ('Widget A (idx = 0)', 't9') | ('Widget A (idx = 0)', 't10') | ('Widget A (idx = 0)', 't11') | ('Widget A (idx = 0)', 't12') | ('Widget A (idx = 0)', 't13') | ('Widget A (idx = 0)', 't14') | ('Widget A (idx = 0)', 't15') | ('Widget B (idx = 1)', 't1') | ('Widget B (idx = 1)', 't2') | ('Widget B (idx = 1)', 't3') | ('Widget B (idx = 1)', 't4') | ('Widget B (idx = 1)', 't5') | ('Widget B (idx = 1)', 't6') | ('Widget B (idx = 1)', 't7') | ('Widget B (idx = 1)', 't8') | ('Widget B (idx = 1)', 't9') | ('Widget B (idx = 1)', 't10') | ('Widget B (idx = 1)', 't11') | ('Widget B (idx = 1)', 't12') | ('Widget B (idx = 1)', 't13') | ('Widget B (idx = 1)', 't14') | ('Widget B (idx = 1)', 't15') | ('Widget C (idx =2)', 't1') | ('Widget C (idx =2)', 't2') | ('Widget C (idx =2)', 't3') | ('Widget C (idx =2)', 't4') | ('Widget C (idx =2)', 't5') | ('Widget C (idx =2)', 't6') | ('Widget C (idx =2)', 't7') | ('Widget C (idx =2)', 't8') | ('Widget C (idx =2)', 't9') | ('Widget C (idx =2)', 't10') | ('Widget C (idx =2)', 't11') |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| m_1 | 10 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 23 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 17 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan |
| m_2 | nan | nan | 15 | nan | nan | nan | 17 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 30 | nan | nan | nan | 23 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 24 | nan | nan | nan | nan | nan | nan | nan | nan |
| m_3 | nan | nan | 23 | nan | nan | nan | 15 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 26 | nan | nan | nan | 21 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 22 | nan | nan | nan | nan | nan | nan | nan | nan |
| m_4 | nan | nan | 27 | nan | nan | nan | 19 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 22 | nan | nan | nan | 18 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | 29 | nan | nan | nan | nan | nan | nan | nan | nan |
| m_5 | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan | nan |
我来帮你搞定这个转换需求!看你的输入DataFrame,列是多层索引结构(每个列名都是包含部件信息和时间点的元组),行是资源名称。我们的核心目标就是把所有非NaN的有效数据提取出来,整理成结构化的列表。
下面是实现这个功能的Python函数,用Pandas处理起来非常顺畅:
import pandas as pd import numpy as np def df_to_structured_list(input_df): # 把行索引的resources转为普通列,方便后续处理 df_with_resources = input_df.reset_index() # 将宽格式DataFrame转成长格式,展开多层列索引 long_format_df = df_with_resources.melt( id_vars='resources', var_name=['widget_info', 'time_point'], value_name='resource_value' ) # 过滤掉值为NaN的无效行 valid_rows = long_format_df[~np.isnan(long_format_df['resource_value'])] # 把每行数据转换成元组,再组合成最终列表 result_list = [tuple(row) for row in valid_rows.values] return result_list
简单拆解一下步骤:
- 第一步
reset_index():把原来作为行索引的resources列转成普通列,这样后续可以一起参与数据转换; - 第二步
melt():这是关键一步,把宽格式的表格转成长格式,每个部件-时间组合都变成单独的一行,同时保留资源名称和对应的值; - 第三步过滤NaN:把没有有效数值的行去掉,只保留有实际数据的条目;
- 最后转成元组列表:把每行的有效数据打包成元组,组合起来就是你要的结构啦。
你可以直接用你的输入DataFrame测试这个函数,比如假设你的DataFrame叫widget_df,调用df_to_structured_list(widget_df)就能得到结果。如果需要调整元组的顺序,或者要从Widget A (idx = 0)这类字符串里拆分出idx信息,随时告诉我,我再帮你修改!
备注:内容来源于stack exchange,提问作者BP130
相关产品推荐
相关产品推荐

