这是我关于StackOverflow的第一个问题,因此欢迎提出如何使问题更清晰的建议。
我的点数据CSV结构如下所示:
OBJECTID,CART_ID,SHAPE
1,ABC,"(1.2, -4.5)"
2,ABD,"(3.8, 9.1)"
在python 3.5中使用petl模块,我试图将SHAPE字符串转换为两个独立的float对象列。使用我从petl文档中理解的内容,我应该能够分三步完成。
a = petl.fromcsv('file.csv')
b = petl.convert(a, 'SHAPE', tuple)
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)
答案 0 :(得分:1)
你没有像petl expects那样的复合表,你仍然有一个字符串。您需要将其传递给另一个函数才能解释它:
>>> ast.literal_eval('(1, 2)')
(1, 2)
将ast.literal_eval()
整合到petl中是留给读者的练习。
答案 1 :(得分:0)
正如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
答案 2 :(得分:0)
使用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 to float。
稍微多一点"邪恶"方法是要意识到表达式是一个有两个浮点数的元组的有效python,所以你可以这样说:
b = petl.convert(a, 'SHAPE', eval)
c = petl.unpack(b, 'SHAPE', ['LAT', 'LON'])