Python训练数据个性化提取 JSON与DICT转换并输出

深度学习或机器学习过程中少不了需要对训练过程进行额外处理,比如我们想观察score的变化,相关差准确率变化的趋势。

除了用模型自带的plot工具,我们也需要自己进行集中处理或对中间过程进行缓存。

原始输入:

{'Role': 'Server #', 'Round': 1, 'Results_raw': {'test_f1': 0.10770681986233807, 'test_total': 609, 'test_avg_loss': 1.9486457109451294, 'test_loss': 1186.7252379655838, 'val_f1': 0.08549080600237736, 'val_total': 542, 'val_avg_loss': 1.949989914894104, 'val_loss': 1056.8945338726044}}
{'Role': 'Server #', 'Round': 2, 'Results_raw': {'test_f1': 0.11019650206846494, 'test_total': 609, 'test_avg_loss': 1.9490487575531006, 'test_loss': 1186.9706933498383, 'val_f1': 0.09533932757526807, 'val_total': 542, 'val_avg_loss': 1.9504367113113403, 'val_loss': 1057.1366975307465}}
{'Role': 'Server #', 'Round': 3, 'Results_raw': {'test_f1': 0.11728175062534404, 'test_total': 609, 'test_avg_loss': 1.9500796794891357, 'test_loss': 1187.5985248088837, 'val_f1': 0.09500389029711606, 'val_total': 542, 'val_avg_loss': 1.9511232376098633, 'val_loss': 1057.508794784546}}
{'Role': 'Server #', 'Round': 4, 'Results_raw': {'test_f1': 0.11653842664371827, 'test_total': 609, 'test_avg_loss': 1.9523628950119019, 'test_loss': 1188.9890030622482, 'val_f1': 0.10123642955228289, 'val_total': 542, 'val_avg_loss': 1.9534810781478882, 'val_loss': 1058.7867443561554}}
{'Role': 'Server #', 'Round': 5, 'Results_raw': {'test_f1': 0.12422168569025195, 'test_total': 609, 'test_avg_loss': 1.9476524591445923, 'test_loss': 1186.1203476190567, 'val_f1': 0.10875485804792952, 'val_total': 542, 'val_avg_loss': 1.948114037513733, 'val_loss': 1055.8778083324432}}
{'Role': 'Server #', 'Round': 6, 'Results_raw': {'test_f1': 0.12414008225265606, 'test_total': 609, 'test_avg_loss': 1.9449809789657593, 'test_loss': 1184.4934161901474, 'val_f1': 0.11250335618480363, 'val_total': 542, 'val_avg_loss': 1.9455983638763428, 'val_loss': 1054.5143132209778}}
{'Role': 'Server #', 'Round': 7, 'Results_raw': {'test_f1': 0.12411816681585039, 'test_total': 609, 'test_avg_loss': 1.9439574480056763, 'test_loss': 1183.8700858354568, 'val_f1': 0.11951172297016435, 'val_total': 542, 'val_avg_loss': 1.9443539381027222, 'val_loss': 1053.8398344516754}}
{'Role': 'Server #', 'Round': 8, 'Results_raw': {'test_f1': 0.12847046900504241, 'test_total': 609, 'test_avg_loss': 1.9428367614746094, 'test_loss': 1183.187587738037, 'val_f1': 0.12268099263223001, 'val_total': 542, 'val_avg_loss': 1.9436607360839844, 'val_loss': 1053.4641189575195}}
{'Role': 'Server #', 'Round': 9, 'Results_raw': {'test_f1': 0.12793590888828985, 'test_total': 609, 'test_avg_loss': 1.9407541751861572, 'test_loss': 1181.9192926883698, 'val_f1': 0.12519074687255302, 'val_total': 542, 'val_avg_loss': 1.941501259803772, 'val_loss': 1052.2936828136444}}
...
{'Role': 'Server #', 'Round': 200, 'Results_raw': {'test_f1': 0.5866941248560479, 'test_total': 609, 'test_avg_loss': 1.7052942514419556, 'test_loss': 1038.524199128151, 'val_f1': 0.5982337308802026, 'val_total': 542, 'val_avg_loss': 1.7150903940200806, 'val_loss': 929.5789935588837}}
{'Role': 'Server #', 'Round': 'Final', 'Results_raw': {'server_global_eval': {'val_loss': 929.5789935588837, 'test_f1': 0.5866941248560479, 'test_total': 609, 'test_avg_loss': 1.7052942514419556, 'test_loss': 1038.524199128151, 'val_f1': 0.5982337308802026, 'val_total': 542, 'val_avg_loss': 1.7150903940200806}}}

我们的提取目标是,获取每一次迭代中的'test_f1'对应的数值。

初步分析可以值,文件中每一round数据结果是按行进行存储。格式是几乎统一的。

所以我们可以将文件用Python按行读取,进行处理,并且将数据处理之后存入一个列表当中。

那剩下的工作就是如何对每行数据进行处理了。

首先给出整体代码:

import ast, json
def fetch_data(file_name):

    f = open(file_name, "r")
    print("begin to fetch the data.")
    # 总信息字典的列表
    data = []

    # 感兴趣的字典的列表
    special_data = []

    special_data_array = []
    line = f.readline()
    last_round = 0
    while line:
        # 因为其他行数和末行的格式有点不同,需要特判
        # print(line)
        row_dict = ast.literal_eval(line)
        # 当前训练回合数
        round = 0
        # 目标值
        test_f1 = 0 
        if row_dict['Round'] != "Final":
            round = int(row_dict['Round'])
            last_round = round
            test_f1 = float(row_dict['Results_raw']['test_f1'])
        else:
            # 最后一行,只是汇总,不代表训练了第last_round+1次
            round = last_round + 1
            test_f1 = float(row_dict['Results_raw']['server_global_eval']['test_f1'])

        # 可以根据自己的需要提取
        special_data.append({round:test_f1})
        special_data_array.append(test_f1)
        data.append(row_dict)

        # 读取下一行数据
        line = f.readline()
        
    f.close()
    # 打印便于观察
    # print(special_data)
    # 以自己需要的格式输出
    jsonStr = json.dumps(special_data)

    jsonFile = open("output_data.json", "w")
    jsonFile.write(jsonStr)
    jsonFile.close()


if __name__=="__main__":
    fetch_data("eval_results.log")

读取每一行样本:

 line = f.readline()

此时line为str格式,注意不能直接调用json.loads()函数,可以观察我们提供的内容中,期待作为key的部分是单引号''包括的,如果不能调整模型输出,我们就不能直接调用json.loads().这样会报错:Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

注意:字符串中,双引号在外围,单引号在内嵌,导致转换失败,可以使用json5进行处理

但是为了方便提取,我们仍然需要对这一行str,且可以得到JSON格式的内容进行处理,这里可以用到。

str to JSON

使用literal_eval

import ast

str1 = "{'a': 1, 'b': 2}"

json1 = ast.literal_eval(str1)

print(type(json1))
print(json1)

# 输出
<class 'dict'>
{'a': 1, 'b': 2}

使用eval

val的作用:将字符串str当成有效的表达式来求值并返回计算结果。即可以通过eval可以把listtupledictstring相互转化。

使用json.loads()

字符串str转json对象,需要使用json模块的loads函数,注意样本特征。

import json
str1 = '{"accessToken": "521de21161b23988173e6f7f48f9ee96e28", "User-Agent": "Apache-HttpClient/4.5.2 (Java/1.8.0_131)"}'

json1 = json.loads(str1)

print(json1)
print(type(json1))

# 输出
{'accessToken': '521de21161b23988173e6f7f48f9ee96e28', 'User-Agent': 'Apache-HttpClient/4.5.2 (Java/1.8.0_131)'}
<class 'dict'>

获取到我们需要的dict之后,就可以层层根据key获取值了。

如果要输出,我们用json.dumps()处理数据,得到我们需要的文本格式,然后用file模块的write进行输出即可。这部分比较灵活。

 比如最理想的输出格式,我们想得到带有缩进的JSON,方便观察,可以添加indent字段,并配合sort_keys让输出内容根据key值进行字典序排列。

import json
print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4))
{
    "4": 5,
    "6": 7
}

最终输出结果呈现如下:

[
    {
        "1": 0.10770681986233807
    },
    {
        "2": 0.11019650206846494
    },
    {
        "3": 0.11728175062534404
    },

    ...

    {
        "199": 0.5853299926818857
    },
    {
        "200": 0.5866941248560479
    },
    {
        "201": 0.5866941248560479
    }
]

 任务达成。


参考资料:

json报错:Expecting property name enclosed in double quotes: line 1 column 2 (char 1)_Activewaste的博客-CSDN博客

【python】str与json类型转换_str转json_sysu_lluozh的博客-CSDN博客

json — JSON encoder and decoder — Python 3.11.3 documentation

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值