【问题标题】:Save results in YAML file with python使用 python 将结果保存在 YAML 文件中
【发布时间】:2016-11-19 09:35:00
【问题描述】:

在搜索上一个答案一小时后,我陷入了这个小问题。 我想将我的代码中的矩阵存储在 .yaml 文件中

我从我的代码中获得了什么

Matrix
[[  1.00665266e+03   0.00000000e+00   5.08285432e+02]
 [  0.00000000e+00   1.01086937e+03   3.45995536e+02]
 [  0.00000000e+00   0.00000000e+00   1.00000000e+00]]

我如何尝试保存此矩阵(mtx 是我代码中的较短名称)

fname = "calibrationC300.yaml"

data = dict(
    Matrix = mtx,
)

with open(fname, "w") as f:
    yaml.dump(data, f, default_flow_style=False)   

但我在 YAML 文件中读到的内容完全错误(只是转换错误?)

Matrix: !!python/object/apply:numpy.core.multiarray._reconstruct
  args:
  - &id001 !!python/name:numpy.ndarray ''
  - !!python/tuple [0]
  - b
  state: !!python/tuple
  - 1
  - !!python/tuple [3, 3]
  - !!python/object/apply:numpy.dtype
    args: [f8, 0, 1]
    state: !!python/tuple [3, <, null, null, null, -1, -1, 0]
  - false
  - !!binary |
    cWM87e1YkEAAAAAAAAAAAIUEEyb5SH1AAAAAAAAAAACp/Z3yc2qQQFv0vPqb5nZAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAPA/

这是我第一次使用 Yaml 文件,我做错了什么? 有没有一种方法可以在 yaml 文件中以简单的形式(我从代码中获取)获取矩阵? 提前谢谢你

【问题讨论】:

  • 你的目标是什么 - 得到适合输入到 numpy 脚本的东西、适合输入到不同工具的便携的东西,或者人类可读的东西?
  • @JohnCarter 更喜欢这三件事。对于我刚刚用 numpy.savez 解决的 numpy 脚本的输入

标签: python numpy yaml


【解决方案1】:

区别在于 float 和 numpy.float64。 Yaml 使用更复杂的方式来表示 numpy.float64。如果您喜欢更易读的 yaml,可以更改为浮动。请参阅以下示例:

print(yaml.dump({'test': 1, 'data':float(0.2)}, default_flow_style=False))
print(yaml.dump({'test': 2, 'data':numpy.float64(0.2)}, default_flow_style=False))

输出是:

data: 0.2

test: 1

data: !!python/object/apply:numpy.core.multiarray.scalar
- !!python/object/apply:numpy.dtype
  args:
  - f8
  - 0
  - 1
  state: !!python/tuple
  - 3
  - <
  - null
  - null
  - null
  - -1
  - -1
  - 0
- !!binary |
  mpmZmZmZyT8=

test: 2

【讨论】:

  • df.to_dict('records') 可以将数据帧转换为普通的python字典
【解决方案2】:

这里唯一的错误似乎是您对 numpy 内部可以并且应该如何转储到 YAML 的期望。

一个简单的检查,看看你得到的YAML是正确的,是loaddump-ed:

import ruamel.yaml
import numpy
import pprint

mtx = [[1.00665266e+03, 0.00000000e+00, 5.08285432e+02],
       [0.00000000e+00, 1.01086937e+03, 3.45995536e+02],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00],]

data = dict(Matrix=mtx)

yaml_str = ruamel.yaml.dump(data, default_flow_style=False)
data = ruamel.yaml.load(yaml_str)
print(data)

给出:

{'Matrix': [[1006.65266, 0.0, 508.285432], [0.0, 1010.86937, 345.995536], [0.0, 0.0, 1.0]]}

numpy 使用的特殊类型转储为简单(且可读)的 YAML,无法保证可以重新加载。对于某些构造来说可能是可能的,尽管它很容易导致歧义,并且 AFAIK 简化不适用于任何 numpy 类型。

当然,您可以在不让numpy 提供其恢复信息的情况下转储该 YAML,方法是:

ruamel.yaml.round_trip_dump(data, sys.stdout)

给出:

Matrix:
- - 1006.65266
  - 0.0
  - 508.285432
- - 0.0
  - 1010.86937
  - 345.995536
- - 0.0
  - 0.0
  - 1.0

更具可读性,但当您再次从其 YAML 表示中 load() 时,它不会成为一个 numpy.multiarray 自动

【讨论】:

  • 在您的示例中,mtx 不是np.multiarray,而是一个常规列表(并且np.multiarray 被此列表覆盖)。你肯定是说mtx = numpy.multiarray([[...], ...])
  • @moi 我当然不是指mtx = numpy.multiarray([[...], ...]),因为这会完全转储 OP 抱怨的不可读 YAML,并且不会为您提供呈现的结果。当然mtx 不是np.multiarray,为什么会这样呢?它们只是在多重赋值语句中被赋予相同的值。您当然可以争辩说,分配给 np.multiarray 在这里没有任何意义,但这是完全不同的。
  • 好的,我明白了。因此,如果它没有任何用途,您可能希望将其从答案中删除,因为它会使人们(至少是我)感到困惑。
【解决方案3】:

我也不是专家,但生成的 yaml 似乎是正确的。您可以看到原始类型默认渲染得很好。对于其他人,您可能需要采取一些措施。阅读此处documentation

祝你好运!

(我没有足够的代表发表评论,否则我会将这篇文章作为评论留下。)

【讨论】:

  • @我会尝试查看您的链接,谢谢。你知道是否有一种方法可以将我的矩阵保存为与我在代码中获得的格式相同的格式? (我赞成你的回答,所以现在你有足够的声誉发表评论!)
  • 从文档看来,您必须创建自己的 yaml.YAMLObject 子类,并指定 reprinit 和 yaml_tag。我认为它已经在某处可用......但我找不到它。如果你只是想序列化,你可能会将矩阵转换为嵌套列表?
  • 我也找不到示例。我想将我的矩阵保存为矩阵,以便将其加载到另一个脚本中。我开始怀疑 YAML 是否不是正确的选择...
  • 就个人而言,我只会使用 yaml 来提高可读性。否则使用 json 或 pickle。
猜你喜欢
  • 2011-03-21
  • 1970-01-01
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 2019-04-04
相关资源
最近更新 更多