Тип данных Распознавание/Угадание данных CSV в python

Моя проблема заключается в обработке данных из больших файлов 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 или даже лучше
  • тип данных отдельного столбца в виде массива

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

Ответ 1

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

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

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

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

Ответ 2

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

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

Возникают два вопроса:

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

Ответ 3

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

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

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

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

Ответ 4

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

if (value - String), то thisType = String;

if (значение DateTime), то thisType - DateTime;

if (значение Decimal), то этот тип является десятичным;

if (значение Integer), то thisType является Integer;

if (value is Boolean), то thisType является булевым;

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