Распознавание типов данных / угадывание данных CSV в python - PullRequest
17 голосов
/ 26 июля 2011

Моя проблема в контексте обработки данных из больших файлов CSV.

Я ищу наиболее эффективный способ определения (то есть предположения) типа данных столбца на основе значений, найденных в этом столбце. Я потенциально имею дело с очень грязными данными. Следовательно, алгоритм должен быть в некоторой степени устойчивым к ошибкам.

Вот пример:

arr1 = ['0.83', '-0.26', '-', '0.23', '11.23']               # ==> recognize as float
arr2 = ['1', '11', '-1345.67', '0', '22']                    # ==> regognize as int
arr3 = ['2/7/1985', 'Jul 03 1985, 00:00:00', '', '4/3/2011'] # ==> recognize as date
arr4 = ['Dog', 'Cat', '0.13', 'Mouse']                       # ==> recognize as str

Итог: я ищу пакет python или алгоритм, который может обнаружить либо

  • схема файла CSV, или даже лучше
  • тип данных отдельного столбца как массив

Метод определения типа данных, представленных в настоящее время в виде строк , работает в аналогичном направлении. Однако меня беспокоит производительность, поскольку я, возможно, имею дело со многими крупными электронными таблицами (откуда берутся данные)

Ответы [ 5 ]

13 голосов
/ 04 августа 2013

Возможно, вас заинтересует эта библиотека на python, которая делает для вас именно такие предположения типов в файлах CSV и XLS:

Он легко масштабируется до очень больших файлов, потоковой передачи данных из Интернета и т. Д.

Существует также еще более простая библиотека-оболочка, которая включает в себя инструмент командной строки с именем dataconverters: http://okfnlabs.org/dataconverters/ (и онлайн-сервис: https://github.com/okfn/dataproxy!)

Основной алгоритм, который определяет тип, находится здесь: https://github.com/okfn/messytables/blob/7e4f12abef257a4d70a8020e0d024df6fbb02976/messytables/types.py#L164

6 голосов
/ 26 июля 2011

Подумав немного об этом, я сам разработал алгоритм:

  • По соображениям производительности: взять образец для каждого столбца (скажем, 1%)
  • запустить сопоставление регулярных выражений для каждой ячейки в образце, проверяя тип данных
  • Выберите соответствующий тип данных для столбца на основе частотного распределения

Два вопроса, которые возникают:

  • Какой размер выборки достаточный? Для небольших наборов данных? Для больших наборов данных?
  • Какой достаточно высокий порог для выбора типа данных на основе частотного распределения?
3 голосов
/ 26 июля 2011

Вы можете попробовать предварительный анализ с помощью регулярных выражений.Например:

import re
pattern = re.compile(r'^-?\d+.{1}\d+$')
data = '123.42'
print pattern.match(data) # ----> object
data2 = 'NOT123.42GONNA31.4HAPPEN'
print pattern.match(data2) # ----> None

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

myregex = {int: r'^-?\d+$', float: r'^\d+.{1}\d+$', ....}

for key, reg in myregex.items():
    to_del = []
    for index, data in enumerate(arr1):
        if re.match(reg,data):
            d = key(data) # You will need to insert data differently depending on function
            ....#---> do something 
            to_del.append(data) # ---> delete this when you can from arr1

Не забывайте '^' вв начале и '$' в конце, если не регулярное выражение может соответствовать части строки и вернуть объект.

Надеюсь, это поможет:)

2 голосов
/ 08 февраля 2012

Я решил ту же проблему в c #. Вот как я построил набор образцов:
Для каждого столбца в CSV я выбрал строку с самым длинным значением, а также строку с самым коротким значением.
Затем я построил массив из первых 50 непустых строк.
Таким образом, в моих выборках было не менее 0 и не более 50 строк, которые охватывали весь диапазон в столбце.
После этого я попытаюсь разобрать от самого широкого определения до самого узкого:

если (значение - строка), то thisType = String;

если (значение равно DateTime), тогда thisType равно DateTime;

если (значение является десятичным), тогда thisType является десятичным;

если (значение - целое число), то thisType - целое число;

если (значение логическое), тогда thisType логическое;

Я использую TryParse в C #, но я уверен, что другие языки будут использовать аналогичные методы.

1 голос
/ 07 августа 2018

Может быть csvsql может быть полезным здесь? Не знаю, насколько это эффективно, но определенно выполняет работу по созданию операторов создания таблиц sql из csvs.

$ csvsql so_many_columns.csv  >> sql_create_table_with_char_types.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...