如何从含字典列表的DataFrame列生成MetricName对应列并保留原列?
解决方案
要实现将字典列表中的每个MetricName转为独立列并填充对应Value,同时保留原DataFrame的其他列,可以按以下步骤操作:
步骤1:导入依赖库
首先确保你已经安装了必要的库,并导入它们:
import pandas as pd from datetime import datetime from tzlocal import get_localzone as tzlocal
步骤2:转换字符串形式的字典列表为实际对象
示例中FinalMetricDataList列存储的是字符串形式的列表,需要先转换为Python可识别的列表对象:
# 将字符串转为实际的列表字典对象 df_sample['FinalMetricDataList'] = df_sample['FinalMetricDataList'].apply(eval)
注意:如果数据来源不可信,
eval存在安全风险,此时可以先将字符串中的datetime和tzlocal替换为JSON可解析格式,再用json.loads解析后转换回datetime对象。
步骤3:提取指标并生成新列
将每行的字典列表转换为{MetricName: Value}的键值对,再扩展为独立列:
# 提取每个指标的名称和对应值,生成指标DataFrame metrics_df = df_sample['FinalMetricDataList'].apply( lambda x: {item['MetricName']: item['Value'] for item in x} ).apply(pd.Series)
步骤4:合并原数据与指标列
将原DataFrame(可选择移除原指标列表列)与新生成的指标列横向合并:
# 合并数据,保留原有的TrainingJobName、TrainingJobArn列 result_df = pd.concat([df_sample.drop('FinalMetricDataList', axis=1), metrics_df], axis=1)
完整代码示例
import pandas as pd from datetime import datetime from tzlocal import get_localzone as tzlocal # 示例数据 data = {'TrainingJobName': ['Training_JOB_NAME1'], 'TrainingJobArn': ["Blahblah"], 'FinalMetricDataList': ["[{'MetricName': 'test:mean_wQuantileLoss', 'Value': 1.0935583114624023, 'Timestamp': datetime.datetime(2022, 10, 20, 7, 45, 6, tzinfo=tzlocal())}, {'MetricName': 'train:loss:batch', 'Value': 3.0625627040863037, 'Timestamp': datetime.datetime(2022, 10, 20, 7, 44, 37, tzinfo=tzlocal())}, {'MetricName': 'train:progress', 'Value': 100.0, 'Timestamp': datetime.datetime(2022, 10, 20, 7, 44, 37, tzinfo=tzlocal())}, {'MetricName': 'train:loss', 'Value': 3.2942464351654053, 'Timestamp': datetime.datetime(2022, 10, 20, 7, 44, 37, tzinfo=tzlocal())}, {'MetricName': 'train:final_loss', 'Value': 3.2942464351654053, 'Timestamp': datetime.datetime(2022, 10, 20, 7, 44, 37, tzinfo=tzlocal())}, {'MetricName': 'train:throughput', 'Value': 385.56353759765625, 'Timestamp': datetime.datetime(2022, 10, 20, 7, 44, 37, tzinfo=tzlocal())}, {'MetricName': 'test:RMSE', 'Value': 22.101428985595703, 'Timestamp': datetime.datetime(2022, 10, 20, 7, 45, 6, tzinfo=tzlocal())}, {'MetricName': 'ObjectiveMetric', 'Value': 22.101428985595703, 'Timestamp': datetime.datetime(2022, 10, 20, 7, 45, 6, tzinfo=tzlocal())}]"]} df_sample = pd.DataFrame(data=data) # 转换字符串为列表对象 df_sample['FinalMetricDataList'] = df_sample['FinalMetricDataList'].apply(eval) # 生成指标列 metrics_df = df_sample['FinalMetricDataList'].apply( lambda x: {item['MetricName']: item['Value'] for item in x} ).apply(pd.Series) # 合并数据 result_df = pd.concat([df_sample.drop('FinalMetricDataList', axis=1), metrics_df], axis=1) # 查看结果 print(result_df.head())
替代方法(explode + pivot)
如果你的数据中存在同一行重复MetricName的情况,可以用以下方式处理:
# 拆分列表为多行 df_exploded = df_sample.explode('FinalMetricDataList') # 提取MetricName和Value df_exploded['MetricName'] = df_exploded['FinalMetricDataList'].apply(lambda x: x['MetricName']) df_exploded['Value'] = df_exploded['FinalMetricDataList'].apply(lambda x: x['Value']) # 透视转换为列 metrics_pivot = df_exploded.pivot( index=['TrainingJobName', 'TrainingJobArn'], columns='MetricName', values='Value' ).reset_index()
内容的提问来源于stack exchange,提问作者Wolfy
相关产品推荐
相关产品推荐

