Использование SypGL и Python для запуска аналитики командной строки

Использование SypGL и Python для запуска аналитики командной строки

7 ноября 2022 г.

Командная строка невероятно мощна, когда дело доходит до обработки данных. Тем не менее, многие из нас, работающих с данными, не пользуются ими. Я могу придумать несколько причин:

  • Плохая удобочитаемость: основное внимание уделяется тому, чтобы свести к минимуму объем ввода, а не тому, насколько удобочитаема последовательность команд.
  • Крутая кривая обучения: множество команд с множеством параметров.
  • Выглядит устаревшим: некоторые из этих инструментов существуют с 70-х годов и предназначены для текстовых файлов с разделителями (а не для современных форматов, таких как JSON и YAML).

Это побудило меня написать инструмент командной строки, который фокусируется на удобочитаемости, простоте изучения и современных форматах данных, используя при этом экосистему командной строки. Кроме того, он также использует экосистему Python! Встречайте SPyQL - SQL с Python посередине:

SELECT 
  date.fromtimestamp(purchase_ts) AS purchase_date,
  sum_agg(price * quantity) AS total
FROM csv('my_purchases.csv')
WHERE department.upper() == 'IT' and purchase_ts is not Null
GROUP BY 1
ORDER BY 1
TO json

SPyQL в действии

Я думаю, что лучший способ познакомиться с SPyQL и освоиться с командной строкой — это открыть терминал и решить проблему. В данном случае мы попытаемся понять географическое распространение вышек сотовой связи. Начнем!

Настройка

Начнем с установки SPyQL:

$ pip3 install -U spyql

и проверьте его версию:

$ spyql --version
spyql, version 0.8.1

Давайте также установим MatplotCLI, утилиту для создания графиков из командной строки, использующую Matplotlib:

$ pip3 install -U matplotcli

Наконец, мы загрузим некоторые образцы данных (вы также можете скопировать и вставить URL-адрес в свой браузер и загрузить оттуда файл):

$ wget https://raw.githubusercontent.com/dcmoura/blogposts/master/spyql_cell_towers/sample.csv

Этот CSV-файл содержит данные о вышках сотовой связи, которые были добавлены в базу данных OpenCellid 10 сентября 2022 года (OCID-diff-cell- файл export-2022-09-10-T000000.csv из проекта OpenCellid, распространяемый без изменений под Международная лицензия Creative Commons Attribution-ShareAlike 4.0).

Проверка данных

Давайте посмотрим на данные, получив первые 3 строки файла:

$ head -3 sample.csv
radio,mcc,net,area,cell,unit,lon,lat,range,samples,changeable,created,updated,averageSignal
GSM,262,2,852,2521,0,10.948628,50.170324,15762,200,1,1294561074,1662692508,0
GSM,262,2,852,2501,0,10.940241,50.174076,10591,200,1,1294561074,1662692508,0

Эту же операцию можно проделать и с SPyQL:

$ spyql "SELECT * FROM csv LIMIT 2" < sample.csv

или

$ spyql "SELECT * FROM csv('sample.csv') LIMIT 2"

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

Одним из преимуществ SPyQL является то, что мы можем легко изменить формат вывода. Давайте изменим вывод на JSON и посмотрим на первую запись:

$ spyql "SELECT * FROM csv('sample.csv') LIMIT 1 TO json(indent=2)"
{
  "radio": "GSM",
  "mcc": 262,
  "net": 2,
  "area": 852,
  "cell": 2521,
  "unit": 0,
  "lon": 10.948628,
  "lat": 50.170324,
  "range": 15762,
  "samples": 200,
  "changeable": 1,
  "created": 1294561074,
  "updated": 1662692508,
  "averageSignal": 0
}

Запрос данных

Сначала посчитаем, сколько записей у нас есть:

$ spyql "SELECT count_agg(*) AS n FROM csv('sample.csv')"
n
45745

Обратите внимание, что функции агрегации имеют суффикс _agg, чтобы избежать конфликтов с функциями Python, такими как min, max и sum. Теперь посчитаем, сколько у нас есть вышек сотовой связи по типу радио:

$ spyql "SELECT radio, count_agg(*) AS n FROM csv('sample.csv') GROUP BY 1 
ORDER BY 2 DESC TO pretty"
radio        n
-------  -----
GSM      31549
LTE      12996
UMTS      1182
CDMA        16
NR           2

Обратите внимание на красивый вывод на печать. Мы можем построить приведенные выше результаты, установив выходной формат в JSON и передав результаты в MatplotCLI:

$ spyql "SELECT radio, count_agg(*) AS n FROM csv('sample.csv') GROUP BY 1 
ORDER BY 2 DESC TO json" | plt "bar(radio, n)"

Matplolib plot created by MatplotCLI using the output of a SPyQL query

Насколько это было легко? :-)

Запрос данных: более сложный пример

Теперь давайте возьмем первые 5 стран, где в этот день было добавлено больше вышек сотовой связи:

$ spyql "SELECT mcc, count_agg(*) AS n FROM csv('sample.csv') GROUP BY 1 ORDER BY 2 DESC LIMIT 5 TO pretty"
  mcc      n
-----  -----
  262  24979
  440   5085
  208   4573
  310   2084
  311    799

MCC – мобильный код страны (262 – код Германии). Первая цифра MCC идентифицирует регион. Вот пример из Википедии:

0: Test networks
2: Europe
3: North America and the Caribbean
4: Asia and the Middle East
5: Australia and Oceania
6: Africa
7: South and Central America
9: Worldwide

Давайте скопируем и вставим приведенный выше список регионов и создадим новый файл с именем mcc_geo.txt. На Mac это так же просто, как $ pbpaste > mcc_geo.txt, но вы также можете вставить его в текстовый редактор и сохранить.

Теперь давайте попросим SPyQL открыть этот файл в формате CSV и распечатать его содержимое:

$ spyql "SELECT * FROM csv('mcc_geo.txt') TO pretty"
  col1  col2
------  -------------------------------
     0  Test networks
     2  Europe
     3  North America and the Caribbean
     4  Asia and the Middle East
     5  Australia and Oceania
     6  Africa
     7  South and Central America
     9  Worldwide

SPyQL обнаружил, что разделителем является двоеточие и файл не имеет заголовка. Мы будем использовать синтаксис colN для обращения к N-му столбцу.

Теперь давайте создадим один объект JSON с таким количеством пар "ключ-значение", как и входных строк. Пусть 1-й столбец ввода будет ключом, а 2-й столбец будет значением, и сохраните результат в новый файл:

$ spyql "SELECT dict_agg(col1,col2) AS json FROM csv('mcc_geo.txt') TO json('mcc_geo.json', indent=2)"

Мы можем использовать cat для проверки выходного файла:

$ cat mcc_geo.json                                               
{
  "0": "Test networks",
  "2": "Europe",
  "3": "North America and the Caribbean",
  "4": "Asia and the Middle East",
  "5": "Australia and Oceania",
  "6": "Africa",
  "7": "South and Central America",
  "9": "Worldwide "
}

Мы объединили все входные строки в словарь Python, а затем сохранили его в виде файла JSON. Попробуйте удалить псевдоним AS json из SELECT, чтобы понять, зачем он нам нужен :-)

Теперь давайте получим статистику по регионам, а не по Центру клиентов. Для этого мы загрузим только что созданный файл JSON (с опцией -J) и выполним поиск в словаре:

$ spyql -Jgeo=mcc_geo.json "SELECT geo[mcc//100] AS region, count_agg(*) AS n 
FROM csv('sample.csv') GROUP BY 1 ORDER BY 2 DESC TO pretty"
region                               n
-------------------------------  -----
Europe                           35601
Asia and the Middle East          5621
North America and the Caribbean   3247
Australia and Oceania              894
Africa                             381
South and Central America            1

Мы выполняем целочисленное деление на 100, чтобы получить первую цифру MCC, а затем ищем эту цифру в только что созданном JSON (который загружается как словарь Python). Вот как мы делаем JOIN в SPyQL через поиск по словарю :-)

Использование библиотек Python в ваших запросах

Еще одно преимущество SPyQL заключается в том, что мы можем использовать экосистему Python. Давайте попробуем сделать еще немного географической статистики. Считаем башни по ячейке H3 (разрешение 5) для Европы. Во-первых, нам нужно установить библиотеку H3:

$ pip3 install -U h3

Затем мы можем преобразовать пары широта-долгота в ячейки H3, подсчитать, сколько башен у нас есть по ячейке H3, и сохранить результаты в CSV:

$ spyql "IMPORT h3 SELECT h3.geo_to_h3(lat, lon, 5) AS cell, count_agg(*) AS n 
FROM csv('sample.csv') WHERE mcc//100==2 GROUP BY 1 TO csv('towers_by_h3_res5.csv')"

Визуализировать эти результаты с помощью Kepler довольно просто. Просто зайдите на kepler. gl/demo и откройте вышеуказанный файл. Вы должны увидеть что-то вроде этого:

Kepler visualization of aggregations by H3 cell (resolution 5) from SPyQL

Заключительные слова

Надеюсь, вам понравился SPyQL и я смог показать вам, насколько просто запрашивать данные из командной строки. В этом первом посте о SPyQL мы лишь слегка касаемся поверхности. Мы можем сделать гораздо больше. В этой статье мы почти не использовали экосистемы Shell и Python. И мы работали с небольшим файлом (SPyQL может обрабатывать файлы размером в гигабайт без ущерба для системных ресурсов). Так что следите за обновлениями!

Попробуйте SPyQL и поделитесь со мной своими мыслями. Спасибо!

Ресурсы


Вы можете найти меня в Tweeter, LinkedIn и Vimeo!

Также опубликовано здесь


Оригинал