Тип данных Распознавание/Угадание данных 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 в С#, но я уверен, что другие языки будут использовать аналогичные методы.