【问题标题】:How do I parse multiple files in Python and extract important information?如何在 Python 中解析多个文件并提取重要信息?
【发布时间】:2019-03-22 14:52:32
【问题描述】:

我正在尝试编写一个程序,该程序重复地从数百个 YAML 文件中读取数据,并将文件中包含的某些信息存储在某种表格中。该程序本质上会解析给定目录中的每个 YAML 文件并提取相关信息,直到每个文件都被成功解析。

其中一个 YAML 文件的内容示例:

%YAML:1.0
camera_rotation_wrt_base: !!opencv-matrix
  cols: 3
  data: [-0.0159428846, 0.0246045925, 0.999570131, -0.999774337, -0.0144301597, -0.0155909406,
    0.0140403481, -0.999593139, 0.024829099]
  dt: f
  rows: 3
camera_translation_wrt_base: [0.4445618987083435, 0.11700689047574997, 1.5018157958984375]
object_rotation_wrt_base: !!opencv-matrix
  cols: 3
  data: [-0.74130547, -0.0615471229, 0.668339849, 0.669196069, -0.144052029, 0.728989482,
    0.0514085107, 0.987654269, 0.147973642]
  dt: f
  rows: 3
object_rotation_wrt_camera: !!opencv-matrix
  cols: 3
  data: [-0.6565323818253673, 0.1588616842697038, -0.737379262582055, -0.07928983462501557,
    -0.9866892288165471, -0.14197683014545748, -0.7501189077886223, -0.03474571781315458,
    0.6603895951165363]
  dt: f
  rows: 3
object_translation_wrt_base: [1.1534364223480225, 0.05951927974820137, 1.3502429723739624]
object_translation_wrt_camera: [0.04407151401699165, 0.16979082390232392, 0.705698973194305]
template_id: 1965

我希望能够将来自 object_rotation_wrt_camera 键的数据键以及 object_translation_wrt_camera 键存储在 CSV 文件中,如下所示:

observation,rotation,translation
1,[-0.53434, 0.023343, .....],[0.54545,0.34344,....]                
2,[-0.52234, 0.3433, .....],[0.65645,0.8787344,....] 
3,[0.32234, 0.6453, .....],[0.622645,0.1787344,....]

在上表中,观测值与 yaml 文件有关,因此对于每个文件,CSV 文件中都存储了一个观测值,用于旋转和平移变量。 (注意:表中使用的句点仅表示旋转和平移变量会继续,因为它们很长)。

最后,我想创建一个最终的 CSV 文件,它与上面的文件类似,但是所有的旋转和平移值都是分开的(这意味着不是一列用于平移,一列用于旋转,而是有 3用于与前一个 CSV 文件列表中的 3 个值有关的翻译,以及与前一个 CSV 文件列表中的 9 个值中的每一个有关的 9 列),如下所示:

observation,tran1,tran2,tran3,rot1,rot2,rot3,rot4,rot5,rot6,rot7,rot8,rot9
1,-0.545434,4.54545,0.343434,.............................................
2,-0.4543,3.3434,0.3534,..................................................

【问题讨论】:

    标签: python parsing yaml


    【解决方案1】:

    我将您的示例存储在两个以 .yaml 结尾的不同文件中,然后运行:

    import sys
    from pathlib import Path
    import csv
    import ruamel.yaml
    
    result = [['observation', 'rotation', 'translation']]
    flatres = ["observation,tran1,tran2,tran3,rot1,rot2,rot3,rot4,rot5,rot6,rot7,rot8,rot9".split(',')]
    yaml = ruamel.yaml.YAML()
    
    for idx, file_name in enumerate(Path('.').glob('*.yaml')):
       txt = file_name.read_text()
       if txt.startswith('%YAML:1.0'):
          txt = txt.replace('%YAML:1.0', "", 1).lstrip()
       data = yaml.load(txt)
       result.append([
         idx+1,
         data['object_rotation_wrt_camera']['data'],
         data['object_translation_wrt_camera'],
       ])
       row = [idx+1]
       row.extend(data['object_translation_wrt_camera'])
       row.extend(data['object_rotation_wrt_camera']['data'])
       flatres.append(row)
    
    writer = csv.writer(sys.stdout)
    writer.writerows(result)
    print('---------')
    writer = csv.writer(sys.stdout)
    writer.writerows(flatres)
    

    给出:

    observation,rotation,translation
    1,"[-0.6565323818253673, 0.1588616842697038, -0.737379262582055, -0.07928983462501557, -0.9866892288165471, -0.14197683014545748, -0.7501189077886223, -0.03474571781315458, 0.6603895951165363]","[0.04407151401699165, 0.16979082390232392, 0.705698973194305]"
    2,"[-0.6565323818253673, 0.1588616842697038, -0.737379262582055, -0.07928983462501557, -0.9866892288165471, -0.14197683014545748, -0.7501189077886223, -0.03474571781315458, 0.6603895951165363]","[0.04407151401699165, 0.16979082390232392, 0.705698973194305]"
    ---------
    observation,tran1,tran2,tran3,rot1,rot2,rot3,rot4,rot5,rot6,rot7,rot8,rot9
    1,0.04407151401699165,0.16979082390232392,0.705698973194305,-0.6565323818253673,0.1588616842697038,-0.737379262582055,-0.07928983462501557,-0.9866892288165471,-0.14197683014545748,-0.7501189077886223,-0.03474571781315458,0.6603895951165363
    2,0.04407151401699165,0.16979082390232392,0.705698973194305,-0.6565323818253673,0.1588616842697038,-0.737379262582055,-0.07928983462501557,-0.9866892288165471,-0.14197683014545748,-0.7501189077886223,-0.03474571781315458,0.6603895951165363
    

    因为你想要的序列中有逗号 存储时,需要引用这些条目,而 Python 的 CSV 编写器会 自动(否则 CSV 的第二行和后续行 将包含三个以上的元素)。

    YAML 1.0 在 2005 年被 YAML 1.1 取代,我还没有付款 特别注意这些版本之间的差异,除了 该指令。 YAML 1.2 自 2009 年以来一直是 YAML 标准。 ruamel.yaml 仅支持具有显式 YAML 1.2(或 1.1)的文件 指令,这就是为什么需要 %YAML:1.0 指令 从这些文件中明确删除。

    如果你有任何“旧式”八进制整数,你可能会遇到麻烦 在您的文件中以及在您的输入示例中未显示的其他一些情况下。

    【讨论】:

    • 这非常有帮助,非常感谢!唯一的问题是,当我尝试根据您的建议指定 ['data'] 时,出现此错误:TypeError: cannot convert dictionary update sequence element #0 to a sequence
    • 如果你尝试做我建议的替代方案,那里有一个错误,我更新了。
    • 好的,我很抱歉含糊其辞。我想要做的就是将旋转和平移数组存储在一个表(或矩阵)中,其中有 2 列,一列用于旋转,一列用于平移。因此,每个 yaml 文件都将被视为一个“观察”,例如,它涉及旋转和平移两个变量。
    • 翻译是list,旋转是dict(并且该dict中data的值又是一个列表。没有数组、表或矩阵,我有不知道您认为这三个之间有什么区别(也不知道这三个是否与 Python 列表相同)。使用 Python 时,您应该遵循其术语。或者显示您预期数据结构的 YAML/JSON/CSV 输出(或它在 python 中的外观)通过更新您的问题(并在您这样做时省略“编辑:”或任何此类内容)
    • 非常感谢您的指导/建议。我已经更新了问题,并更具体地说明了我相信的目标。
    猜你喜欢
    • 2015-04-19
    • 2015-06-07
    • 2020-07-21
    • 2018-05-23
    • 1970-01-01
    • 2013-08-17
    • 2021-11-22
    • 2014-01-07
    • 1970-01-01
    相关资源
    最近更新 更多