【问题标题】:Convert string to tuple using petl使用 petl 将字符串转换为元组
【发布时间】:2016-12-02 06:27:35
【问题描述】:

这是我在 StackOverflow 上的第一个问题,因此欢迎提出如何使问题更清晰的建议。

我有一个点数据的 CSV,其结构如下所示:

OBJECTID,CART_ID,SHAPE
1,ABC,"(1.2, -4.5)"
2,ABD,"(3.8, 9.1)"

使用 python 3.5 中的 petl 模块,我试图将 SHAPE 字符串转换为两个单独的浮点对象列。使用我从petl 文档中了解的内容,我应该能够分三个步骤完成。

  1. 打开 CSV:a = petl.fromcsv('file.csv')
  2. 将 SHAPE 从字符串转换为元组:b = petl.convert(a, 'SHAPE', tuple)
  3. 使用 .unpack() 将元组分成两列:c = petl.unpack(b, 'SHAPE', ['LAT', 'LON']

我相信这会生成一个如下所示的 CSV 文件:

OBJECTID,CART_ID,LAT,LON
1,ABC,1.2,-4.5
2,ABD,3.8,9.1

相反,.convert() 产生:

OBJECTID,CART_ID,SHAPE
1,ABC,('(', '1', '.', '2', ',', ' ', '-', '4', '.', '5', ')')

任何关于 a) .convert() 正在做什么或 b) 如何重组 CSV 的帮助将不胜感激。

谢谢。

完整代码:

import petl
a = petl.fromcsv('file.csv')
petl.look(a)
b = petl.convert(a, 'SHAPE', tuple)
petl.look(b)
c = petl.unpack(b, 'SHAPE', ['LAT', 'LON']
petl.look(c)

【问题讨论】:

    标签: python python-3.x csv petl


    【解决方案1】:

    你没有像 petl expects 这样的复合表,你还有一个字符串。您需要将其传递给不同的函数才能对其进行解释:

    >>> ast.literal_eval('(1, 2)')
    (1, 2)
    

    ast.literal_eval() 集成到petl 中作为练习留给读者。

    【讨论】:

      【解决方案2】:

      正如 Ignacio 所说,您仍然需要拆分字符串数据。这可以使用strip()split() 来完成,或者按照建议使用ast.literal_eval() 来安全地评估最后一列的内容。

      下面的例子使用了这个。它会读取您的 CSV 文件,将最后一列拆分为其组成部分并创建一个新的输出 CSV 文件:

      import csv
      import ast
      
      with open('input.csv', newline='') as f_input, open('output.csv', 'w', newline='') as f_output:
          csv_input = csv.reader(f_input)
          csv_output = csv.writer(f_output)
          csv_output.writerow(next(csv_input)[:2] + ['LAT', 'LON'])
      
          for row in csv_input:
              csv_output.writerow(row[:2] + list(ast.literal_eval(row[2])))
      

      给你一个output.csv,看起来像:

      OBJECTID,CART_ID,LAT,LON
      1,ABC,1.2,-4.5
      2,ABD,3.8,9.1
      

      【讨论】:

        【解决方案3】:

        使用 PETL,您可以只使用 capture 和正则表达式:

        b = petl.capture(a, 'SHAPE', r'\(\s*([-0-9.]+)\s*,\s*([-0-9.]+)\s*\)', ['LAT', 'LON'])
        c = petl.convert(b, ['LAT', 'LON'], float)
        

        这应该会检测数字并创建 2 个名为 LAT 和 LON 的新列,但它们将是字符串,因此您可能需要在此之后使用 convert 来浮动。

        稍微更“邪恶”的方法是意识到表达式对于具有两个浮点数的元组是有效的python,所以你可以说:

        b = petl.convert(a, 'SHAPE', eval)
        c = petl.unpack(b, 'SHAPE', ['LAT', 'LON'])
        

        【讨论】:

        • ast.literal_eval 会减少邪恶:P
        猜你喜欢
        • 1970-01-01
        • 2017-04-30
        • 2012-01-19
        • 1970-01-01
        • 2016-03-14
        • 1970-01-01
        相关资源
        最近更新 更多