2016-12-02 3 views
1

Это мой первый вопрос о StackOverflow, поэтому предложения о том, как сделать этот вопрос яснее, всегда приветствуются.Преобразование строки в кортеж с использованием petl

У меня есть CSV точечных данных структурированы, как показано ниже:

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

Использование модуля petl в Python 3.5, я пытаюсь преобразовать строку SHAPE в двух отдельных столбцах объектов с плавающей точкой. Используя то, что я понял из документации petl, я должен сделать это в три этапа.

  1. Открыть CSV: a = petl.fromcsv('file.csv')
  2. Преобразовать SHAPE из строки в виде кортежа: b = petl.convert(a, 'SHAPE', tuple)
  3. Split кортеж на две колонки с помощью .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', ')') 

Любая помощь на), что .convert() делает, или б) как реструктурировать 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) 

ответ

1

Вы не составное таблицу petl expects, вы по-прежнему есть строка. Вы должны передать его на другую функцию для того, чтобы интерпретировать его:

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

Интеграция ast.literal_eval() в petl остается в качестве упражнения для читателя.

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 
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, но они будут Strin gs, поэтому после этого вам может понадобиться использовать convert to float.

Чуть более «злой» подход должен был бы понимать, что выражение справедливо питон для кортежа с двумя поплавками, так что вы могли бы просто сказать:

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

'ast.literal_eval' бы сделать меньше зла :П –

Смежные вопросы