Відкритий посібник з відкритих даних

2. Формати даних

У розділі йдеться про формати запису даних — бінарні і текстові, структурні і табличні. Дається поняття людиночитаності і машиночитаності формату.

Вимірюючи явища світу, людина не може покладатися на свою пам’ять. Тому отримані дані належним чином записують. Записи даних — байдуже, на глиняній табличці чи в базі даних — мають спільні властивості. Зокрема, недотримання порядку записування — формату — може зробити дані незрозумілими не лише іншій людині, а й самій авторці запису.

Оскільки дані — не просто числа, а числа, пов’язані з певними вимірами певного об’єкта реальності, найприроднішим способом організації такої інформації є список. Вимірюючи певний об’єкт, людина складає список його вимірів (довжина, ширина, вага) зі значеннями. Якщо об’єктів декілька, утворюється список списків, який зручно оформлювати у таблицю, де перший стовпчик є списком об’єктів, а подальші відповідають кожній з вимірюваних властивостей.

В письмовій формі дані найчастіше записують у форматі таблиць і систем пов’язаних між собою таблиць — від багатосотсторінкових довідників до рукописних амбарних книжок. Тому не дивно, що першим практичним додатком, що сприяв поширенню персональних комп’ютерів, був VisiCalc на apple ][ — електронна таблиця, що мала всі основні риси тих електронних таблиць, що лишаються найпопулярнішим засобом організації і обробки даних на ПК досі.

Електрона таблиця не є панацеєю, але виступає «швейцарським армійським ножем» роботи з даними: в неї досить зручно вводити зібрані дані, з неї досить зручно зчитувати дані, в ній можна виконувати операції з обробки даних. Прийоми роботи з електронною таблицею на прикладі Microsoft Excel розглянуто у відповідному додатку.

Хоча сучасні електронні таблиці дозволяють працювати з багатьма таблицями і виконувати досить складні операції із вміщеними в них даними, для справді великих наборів внутрішньо пов’язаних даних і операцій з ними використовуються системи керування базами даних, такі як MySQL та його форк MariaDB, PostgreSQL, Microsoft Access, тощо.

Крім того, для багатьох задач роботи з даними існують спеціалізовані програми, наприклад, обліково-бухгалтерські, геоінформаційні, тощо.

Бази даних і спеціалізовані програми можуть імпортувати—експортувати частини (фрагменти) даних як таблиці, але використовують і складніші способи їх запису, що дозволяють зберігати їхню структуру.

З точки зору простого користувача, кожна програма працює зі своїми специфічними форматами файлів, які часто навіть називають за іменами програм (частіше чуємо «надішли мені в Ворді» а не «надішли мені в докікс» чи «надішли мені в офісопенексімел»). Просунутіший користувач знає, що деякі програми вміють відкривати файли інших програм, і записувати файли інших програм, з більшим чи меншим успіхом. Таким чином, можна казати про типи форматів файлів (електронна таблиця, документ офісного редактора, растрове зображення, тощо). Файли одного типу менш-більш подібні за можливостями між собою.

Але для кращого розуміння варто зазирнути цим форматам файлів, образно кажучи, під капот.

Бінарні і текстові файли

Типовий комп’ютер працює з двома станами — нулем (струму немає) і одиницею (струм є).1 Послідовності цих станів являють собою двійкові числа. Якщо файл складається просто з нулів та одиниць, такий файл називається бінарним.

Бінарні файли можуть бути як послідовностями команд процесора — програмами, так і файлами даних програм, наприклад формат Microsoft Excel .xls (основний формат до версії 2007 року) є бінарним. Бінарними є практично всі файли відео, зображень і звуку.

З іншого боку, ще з часів розробки телеграфії існує практика кодування символів (літер, цифр, тощо) числами, зокрема двійковими. Файл, що складається з потоку кодованих символів, називається текстовим.

про таблиці кодування

Існує велика кількість таблиць кодування текстових файлів. Найстандартнішою з них є ASCII, вона містить лише числа, літери латинської абетки і деякі спеціальні символи 2.

Поширена у нас таблиця кодування з символами кирилиці, відома як Windows-1251 чи CP-1251, до 127 символу збігається з ASCII. Проте в ній неможливо використати, наприклад, латинські літери з діакритикою типу ç чи å або математичні символи типу ⋽ чи ∀. Тому безпечніше тримати текстові дані в іншій таблиці кодування — Unicode, яка містить символи всіх живих і багатьох мертвих писемностей, а також багато спецсимволів — від математичних позначок до смайликів. Її різновид UTF-8, крім того, сумісний з ASCII (перші 127 символів співпадають), що зробило його «основним кодуванням 21 століття». Саме це кодування вважається кодуванням за змовчанням, наприклад, в родині мов XML. Існують інші різновиди унікода, вони мають таку само таблицю символів, але використовують інші підходи до побудови кодів і несумісні з ASCII.

Для перекодування між різними таблицями кодувань застосовуються спеціальні програми, наприклад, recode чи iconv та online-сервіси, типу 2cyr.com/decode, орієнтованого в тому числі на перекодування в читабельний вигляд кількаразово неправильно перекодованих текстів.

людино- і машиночитані дані

В довколакомп’ютерному світі ми часто стикаємося із поняттями «людиночитаності» та «машиночитаності» формату. Їхні значення не зовсім такі, як це зрозуміло інтуїтивно, зокрема «людиночитаний» не означає «легко читаний людиною».

Машиночитаним називають формат стандартною комп’ютерною мовою, що може бути зчитаний автоматично броузером чи іншою комп’ютерною системою. Документи офісних редакторів документів та PDF-файли легко читані людиною, але, як правило, складні для машинної інтерпретації. Такі формати як XML, JSON, CSV із заголовками колонок є машиночитаними форматами. HTML, як структурна мова розмічування, за правильного застосування в поєднанні з мікроформатами, може бути одночасно людино- і машиночитаним форматом. За належного використання засобів структурування, документи текстових редакторів теж можуть бути машиночитанми.

Людиночитаними називають такі формати, які можна відкрити за допомогою простого текстового редактора, типу віндівського Блокнота і щось там розібрати або відредагувати. Тобто, цілком читабельний текст у зображенні не є ані машиночитаним, ані людиночитаним.

Текстові файли мають перед бінарними дві переваги — вони «людиночитані» і менш прив’язані до конкретної програми. Це означає, що вони можуть бути відредаговані будь-яким текстовим редактором (не варто плутати текстові редактори типу примітивного Блокнота чи супернавороченого EMACSа з редакторами документів типу Word, Pages чи Writer — це принципово різні програми) або навіть скриптом, а не лише тією програмою, якою їх створено. Як літерами на папері можна написати звіт, роман, формулу, таблицю, тощо, так і всередині текстового файла можна створювати найрізноманітніші структури — від вихідного коду різних мов програмування, текстів та даних із застосуванням числених мов розмічування, зокрема, HTML, до цілих файлових систем із бінарними файлами всередині.

З іншого боку, бінарні файли значно компактніші за текстові. Проте і їх можна привести до компактнішого стану, використовуючи алгоритми компресії, що може відбуватися як на рівні одного файла чи групи файлів (так працюють програми-архіватори типу ZIP, RAR, 7Z, bzip2, тощо), так і на рівні файлової системи чи протоколу передачі. Алгоритми компресії стискають текстові файли дуже ефективно, тому на поточний момент значна кількість широковживаних форматів файлів є надбудовами над текстовим файлом або над стисненим каталогом, що містить текстові і бінарні файли різних форматів.

Щодо файлів-каталогів

Файли багатьх широковживаних сучасних форматів є саме зтисненими (як правило, ZIP’ом) каталогами, що дозволяє досить елегантні методи часткового експорту даних. Наприклад, для експорту зображень з Word’івського .docx, Open/LibreOffice .odt або електронної книжки .epub досить розархівувати їх (створивши копію з розширенням zip, або просто за допомогою команди unzip -d куди_розпакувати файл.docx) і взяти файли зображень з каталогів word/media в .docx, Pictures в .odt або media в .epub. Можна відредагувати ці зображення і знову стиснути каталог, пере’менувавши з .zip на відповідний формат — все працюватиме.

Отож, розгляньмо деякі формати текстових файлів, що використовуються для запису даних.

Значення з роздільниками. CSV

Найпростіше записати дані у файл, відокремлюючи значення якимось роздільником. Це може бути пробіл, новий рядок, табулятор, тощо, але найбільшого поширення набуло використання коми3.

Формат, де поля значень розділено комами, називається CSV, Comma Separated Values, і це найрозповсюдженіший формат для збереження табличних даних у текстовий файл.

CSV дозволяє записати не лише список значень, але й просту таблицю, починаючи кожен рядок таблиці з нового рядка. Перший рядок може містити заголовки стовпчиків таблиці. В CSV неоднакова кількість полів даних (комірок таблиці) у кожному записі (рядку) вважається помилкою, і такий файл не обробляється. Поле даних може охоплюватися подвійними лапками (“), наприклад, для включення в нього коми або символу нового рядка, що не є роздільниками.

щодо RFC документів

Багато форматів файлів розроблено відкритими групами зацікавлених осіб і організацій, тому технічні документи, що містять повний опис вимог до формату називаються RFC (абревіатура від Request For Comments). Наприклад, докладніше про вимоги і можливості CSV можна прочитати (англійською) в RFC4180

Спостереження за цінами на черешні з початку цього розділу у форматі CSV можуть виглядати наступним чином:

Продавець, Ціна, Якість (бал)
"Пані в 1 ряді", 35, 4
"Пан в кашкеті", 35, 3
"Пан з акцентом", 40, 5
"Бабуся при виході", 30, 3

Фактично, це табличка, і після імпорту до електронної таблиці це виглядатиме приблизно так:

  A B C
1 Продавець Ціна Якість (бал)
2 Пані в 1 ряді 35 4
3 Пан в кашкеті 35 3
4 Пан з акцентом 40 5
5 Бабуся при виході 30 3

щодо CSV і таблиць кодування текстових файлів

Поширене бачення CSV як де-факто стандарту запису табличних даних. Справді, дані в такому форматі імпортують і експортують чи не всі електронні таблиці та бази даних. Не менш важливо, що в CSV можна зберегти лише самі дані — без формул, макросів, тощо, які не є даними, а методами їх обробки, і які тою чи іншою мірою інкорпорують файли електронних таблиць.

Але є важливе «але» — кодування. Якщо дані є чистим ASCII, проблем немає, Але текстові комірки можуть містити кирилицю, латинську діакритику, тощо. Здавалося б, у епоху, коли унікод UTF-8 став найпотужніше підтримуваним стандартом кодування текстових файлів, і дуже часто вважається дефолтним кодуванням, досить завжди кодувати CSV в UTF-8. Але Microsoft Excel не дає можливості вибирати кодування для CSV-файлів, кодуючи їх у стандартне системне восьмибітне кодування, для українізованої чи русифікованої Вінди це буде Windows-1251 (прощавай латинка з діакритикою), а для американської — Windows-1252 (прощавай кирилиця). Але для Екселя на Маку це будуть MacUkraine, MacCyrillic і MacRoman відповідно.

Для вирішення цієї проблеми можливі кілька підходів:

  1. зберігати не в CSV, а в унікодовий текст (роздільником буде табулятор) і переробляти отримані файли на CSV заміною табуляторів на коми.
  2. Встановити відповідне розширення (add-in) до Екселя (сторінка англійською).
  3. Використовувати Google Spreadsheets чи Open/LibreOffice Calc. Важливо пам’ятати, що Calc показуватиме діалог вибору кодування під час збереження в CSV, якщо відкритий файл є файлом електронної таблиці, якщо відкрити ним CSV у певному кодуванні, він зберігатиме CSV в тому ж кодуванні.

Структуровані дані. XML

Текстовий файл може містити структури, складніші за просту таблицю. Для цього використовується розмічування відкривними і закривними символами чи послідовностями символів, подібне до використання дужок в записі математичних прикладів. Вкладання таких елементів може кодувати деревуваті ієрархічні структури даних. Вихідний код багатьох мов програмування організований саме так, але щодо використовуваних з цією метою символів та деталей синтаксису існує багато варіантів. Зокрема, в якості обмежувачів можуть використовуватися звичайні (), фігурні {}, прямокутні [] дужки, тощо.

XML

Екстремальний приклад дужок дає родина мов розмічування SGML/XML, найпоширенішим прикладом якої є мова веб-сторінок HTML. В цих мовах дужки називаються теґами, які разом з охоплюваним ними вмістом становлять елементи. Відкривний теґ може містити атрибути — пари «ім’я-значення». Теґи виглядають як <ім'я-елемента ім'я-атрибута="значення"> Вміст, що може містити інші елементи </ім'я-елемента>. Весь документ мовами цієї родини являє собою кореневий елемент, що містить всі інші елементи — тобто, є деревом.

Описова потужність XML дуже велика, і ті самі дані можна записати у XML багатьма способами. Наш приклад з черешнями може виглядати так

<?xml version="1.0" encoding="UTF-8" ?>
<mrkt>
  <cherries seller="Пані в 1 ряду"  price="35" score="4"/>
  <cherries seller="Пан в кашкеті"  price="35" score="3"/>
  <cherries seller="Пан з акцентом" price="40"  score="5"/>
  <cherries seller="Бабуся при виході" price="30" score="3"/>
</mrkt>

а може і так,

<?xml version="1.0" encoding="UTF-8" ?>
<cherries>
  <seller>
    <id>Пані в 1 ряду</id>
    <price>35</price>
    <score>4</score>
  </seller>
  <seller>
    <id>Пан в кашкеті</id>
    <price>35</price>
    <score>3</score>
  </seller>
  <seller>
    <id>Пан з акцентом</id>
    <price>5</price>
    <score>40</score>
  </seller>
  <seller>
    <id>Бабуся при виході</id>
    <price>30</price>
    <score>3</score>
  </seller>
</cherries>

і ще в багато різноманітних способів. Деталі того, як саме організовано дерево даних, і де — в атрибутах чи у вмісті дочірніх елементах містяться значення, залежать від моделі явища, способів використання файла даних, смаку розробника формату кодування тощо.

Строго форматовані XML файли (прикладів вище це стосується) можна імпортувати до електронних таблиць. Але це стосується не будь-яких формально правильних XML файлів, тож до такого імпорту треба ставитися уважно і контролювати, чи всі потрібні дані потрапили до таблиці. Наприклад, якщо у нас частина даних у атрибутах, а частина — у вмісті елементів, проблем не уникнути.

Щодо даних у HTML

Важливо пам’ятати, що мова веб-сторінок HTML, принаймні в одному з двох своїх синтаксисів, є різновидом XML (а в другому дуже до нього близька). Наприклад, наш приклад про черешні у HTML таблиці виглядатиме так:

<table>
  <tr>
   <th>Продавець</th>
   <th>Ціна</th>
   <th>Якість (бал)</th>
  </tr>
  <tr>
    <td>Пані в 1 ряді</td>
    <td>35</td>
    <td>4</td>
  </tr>
  <tr>
    <td>Пан в кашкеті</td>
    <td>35</td>
    <td>3</td>
  </tr>
  <tr>
    <td>Пан з акцентом</td>
    <td>40</td>
    <td>5</td>
  </tr>
  <tr>
    <td>Бабуся при виході</td>
    <td>30</td>
    <td>3</td>
  </tr>
</table>

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

Не-мова-розмітки YAML і формат JSON

Мова YAML (рекурсивний акронім YAML Ain’t Markup Language — «YAML не є мовою розмітки») призначена для запису структурованих даних, однаково придатних для сприйняття людиною і зчитування машиною. Її створено з урахуванням сумних аспектів досвіду впровадження мов родини XML як мову саме збереження даних а не розмічування тексту.

Наприклад, на наш обридлий приклад нею може виглядати так (роздільниками виступають рядки, ієрархію задано відступами):

---
черешні:
  -  продавець: "Пані в 1 ряді"
     ціна: 35
     якість: 4
  -  продавець: "Пан в кашкеті"
     ціна: 35
     якість: 3
  -  продавець: "Пан з акцентом"
     ціна: 40
     якість: 5
  -  продавець: "Бабуся при виході"
     ціна: 30
     якість: 3
...

або так (роздільниками виступають дужки, квадратові для списків, фігурні для списків пар «параметр-значення»):

---
черешні: [{продавець: "Пані в 1 ряді", ціна: 35, якість: 4}, {продавець:
"Пан в кашкеті", ціна: 35, якість: 3}, {продавець: "Пан з акцентом",
ціна: 40, якість: 5}, {продавець: "Бабуся при виході", ціна: 30, якість: 3}]
...

YAML має багато цікавих можливостей, але більш поширеним засобом запису даних стала його синтаксична підмножина, що одночасно є синтаксичною підмножиною JavaScript, JSON. Саме так, JSON можна прочитати як парсером YAML, так і парсером JavaScript. Для перетворення другого прикладу YAML на JSON досить охопити його фігурними дужками і взяти кожен текстовий елемент в лапки. JSON не чутливий до відступів, тому після форматування для читабельності й краси ми отримаємо це:

{
  "черешні": [
    
    {
      "продавець": "Пані в 1 ряді",
      "ціна": "35",
      "якість": "4"
    },
    {
      "продавець": "Пан в кашкеті",
      "ціна": "35",
      "якість": "3"
    },
    {
      "продавець": "Пан з акцентом",
      "ціна": "40",
      "якість": "5"
    },
    {
      "продавець": "Бабуся при виході",
      "ціна": "30",
      "якість": "3"
    }
  ]
  
}

щодо форматування і валідування

Машиночитані формати даних дуже чутливі до синтаксичних помилок. Тому для перевірки форматування використовуються спеціальні інструменти — валідатори.

Валідатори JSON
jsonformatter.curiousconcept.com — валідатор і форматтер
Валідатори YAML
codebeautify.org/yaml-validator — валідатор
yaml-online-parser.appspot.com — валідатор і конвертер у JSON та Python
codebeautify.org/yaml-to-json-xml-csv — валідатор і конвертер у JSON, XML та CSV

Якщо не бути програмувальником чи не співпрацювати з програмувальником, дані в структурованих форматах — XML, JSON, YAML — для аналізу за допомогою електронної таблиці перетворюють на CSV й імпортують.

Для конвертування можна використати, наприклад, онлайн-інструмент http://www.convertcsv.com/json-to-csv.htm , що дозволяє конвертувати із табличного формату (CSV) у структуровані формати (XML, JSON, YAML, GeoJSON, KML, SQL) і навпаки, транспонувати табличні дані (міняти місцями рядки і колонки) та інше. Також для перетворення форматів можна використати програму Open Refine, роботу з якою — в основному в галузі очистки даних — розглянуто в наступному розділі.


  1. Для любителів зайвих знань зазначимо, що бінарні комп’ютери — не єдино можливі, зокрема розроблялися машини з трьома станами (-, 0, +)
  2. Для любителів зайвих знань зазначимо, що ті самі символи в інших таблицях кодування розташовані інакше, інколи назагал подібно до ASCII з деякими відхиленнями, наприклад MacRoman, а інколи зовсім не подібно, наприклад, свого часу поширена на великих комп’ютерах (мейнфреймах) EBCDIC
  3. Для нас, звиклих використовувати кому як десятковий розділювач, цей вибір здається дещо незручним, але позаяк в англійській і багатьх інших мовах таким розділювачем є крапка, ми вже і самі часом пишемо не 3,14159… а 3.14159…