Автоопределение наличия заголовков CSV в файле - PullRequest
19 голосов
/ 20 апреля 2010

Короткий вопрос: Как автоматически определить, есть ли в CSV-файле заголовки в первой строке?

Подробности: я написал небольшой механизм синтаксического анализа CSV, который помещает данные в объект, к которому я могу получить доступ (приблизительно) в базе данных в памяти. Оригинальный код был написан для анализа стороннего CSV с предсказуемым форматом, но я бы хотел использовать этот код более широко.

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

Я полагаю, мне придется проанализировать первые 3? строки файла CSV и найдите шаблон некоторого вида для сравнения с заголовками. У меня кошмары из трех особенно плохих случаев, в которых:

  1. Заголовки по какой-то причине содержат числовые данные
  2. Первые несколько строк (или большие части CSV) равны нулю
  3. Там заголовки и данные выглядят слишком похожими, чтобы отличать их друг от друга

Если я могу получить «наилучшее предположение» и заставить парсер выйти из строя с ошибкой или выдать предупреждение, если он не может решить, это нормально. Если это что-то, что будет чрезвычайно дорогостоящим с точки зрения времени или вычислений (и займет больше времени, чем это должно спасти меня), я с радостью откажусь от этой идеи и вернусь к работе над «важными вещами».

Я работаю с PHP, но это кажется мне скорее алгоритмическим / вычислительным вопросом, чем вопросом, зависящим от реализации. Если есть простой алгоритм, который я могу использовать, отлично. Если вы можете указать мне на некоторую уместную теорию / обсуждение, это тоже было бы здорово. Если есть гигантская библиотека, которая выполняет обработку естественного языка или 300 различных видов анализа, мне это не интересно.

Ответы [ 6 ]

15 голосов
/ 20 апреля 2010

Как уже отмечали другие, вы не можете сделать это со 100% надежностью. Однако в некоторых случаях полезно получить «в основном правильное» - например, инструменты для работы с электронными таблицами с функцией импорта CSV часто пытаются выяснить это самостоятельно. Вот несколько эвристик, которые указывают на то, что первая строка не заголовок:

  • В первой строке есть столбцы, которые не являются строками или являются пустыми
  • Не все столбцы первого ряда уникальны
  • Первая строка содержит даты или другие распространенные форматы данных (например, xx-xx-xx)
6 голосов
/ 20 апреля 2010

В самом общем смысле это невозможно. Это действительный CSV-файл:
Имя
Jim
Том
Билл

Большинство читателей csv просто принимают hasHeader в качестве опции и позволяют вам передавать свой собственный заголовок, если хотите. Даже в том случае, если вы думаете, что можете обнаружить, что, будучи символьными заголовками и числовыми данными, вы можете столкнуться с катастрофическим отказом. Что если в вашей колонке есть список BMW серии?
M
3 * * +1010 5
7

Вы обработаете это неправильно. Хуже всего то, что вы потеряете лучшую машину!

3 голосов
/ 20 апреля 2010

В чисто абстрактном смысле я не думаю, что есть надежный алгоритмический ответ на ваш вопрос, поскольку он сводится к следующему: «Как отличить данные A от данных B, если я ничего не знаю ни о одном из них?». Всегда будет потенциал для dataA быть неотличимым от dataB. Тем не менее, я бы начал с простого и добавлял только сложность по мере необходимости. Например, если исследовать первые пять строк, для данного столбца (или столбцов), если все типы данных в строках 2-5 одинаковы, но отличаются от типа данных в строке 1, существует высокая вероятность того, что строка заголовка присутствует ( увеличенные размеры выборки уменьшают вероятность ошибки). Это (как бы) решит # 1 / # 3 - возможно, вызовет исключение, если все строки заполнены, но данные неразличимы, чтобы вызывающая программа могла решить, что делать дальше. Для # 2, просто не считайте строку как строку, если только и до тех пор, пока она не извлечет ненулевые данные ... это будет работать во всех, кроме пустого файла (в этом случае вы нажмете EOF). Он никогда не будет надежным, но может быть «достаточно близко».

1 голос
/ 11 февраля 2019

Эта статья содержит несколько хороших советов:

По сути, вы выполняете статистический анализ столбцов на основе того, содержит ли первая строка строку, а остальные номера строк или что-то в этом роде.

http://penndsg.com/blog/detect-headers/

1 голос
/ 20 апреля 2010

Это действительно зависит от того, насколько «общим» должен быть ваш инструмент. Если данные всегда будут числовыми, вам будет легко, если вы будете использовать нечисловые заголовки (что выглядит довольно справедливым предположением).

Но, кроме того, если вы еще не знаете, какие шаблоны присутствуют в данных, вы не сможете их проверить заранее.

FWIW, я на самом деле только что написал скрипт для анализа некоторых вещей из TSV, все из того же источника. Подход источника к заголовкам / форматированию был настолько разбросан, что имело смысл просто заставить скрипт задавать мне вопросы из командной строки во время выполнения. (Это заголовок? Какие столбцы важны?). Так что никакой автоматизации, но это позволяет мне пролистывать наборы данных, над которыми я работаю, вместо того, чтобы пытаться предугадывать каждый забавный случай форматирования. Кроме того, мои ответы сохраняются в файле, поэтому мне нужно участвовать только один раз для каждого файла. Не идеально, но эффективно.

0 голосов
/ 27 июля 2014

Если ваш CSV имеет такой заголовок.

ID, имя, адрес электронной почты, дата 1, john, john@john.com, 12 января 2020

Тогда выполнить filter_var (str, FILTER_VALIDATE_EMAIL) в строке заголовка не удастся. Так как адрес электронной почты находится только в строке данных. Поэтому проверьте строку заголовка для адреса электронной почты (при условии, что ваш CSV содержит адреса электронной почты).

Вторая идея. http://php.net/manual/en/function.is-numeric.php Проверьте строку заголовка на is_numeric, скорее всего, строка заголовка не содержит числовых данных. Но, скорее всего, строка данных будет иметь числовые данные.

Если вы знаете, что в ваших столбцах есть даты, то проверка строки заголовка для даты также будет работать.

Очевидно, вам нужен тип данных, который вы ожидаете. Я "ожидаю" адреса электронной почты.

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