U-SQL Разделить файл CSV на несколько файлов на основе различных значений в файле

У меня есть данные в Azure Data Lake Store, и я обрабатываю имеющиеся там данные с помощью Azure Data Analytic Job с U-SQL. У меня есть несколько файлов CSV, которые содержат пространственные данные, подобные этому:

Файл_20170301.csv

    longtitude| lattitude | date         | hour | value1
    ----------+-----------+--------------+------+-------
    45.121    | 21.123    | 2017-03-01   | 01   | 20
    45.121    | 21.123    | 2017-03-01   | 02   | 10
    45.121    | 21.123    | 2017-03-01   | 03   | 50
    48.121    | 35.123    | 2017-03-01   | 01   | 60
    48.121    | 35.123    | 2017-03-01   | 02   | 15
    48.121    | 35.123    | 2017-03-01   | 03   | 80

Файл_20170302.csv

    longtitude| lattitude | date         | hour | value1
    ----------+-----------+--------------+------+-------
    45.121    | 21.123    | 2017-03-02   | 01   | 20
    45.121    | 21.123    | 2017-03-02   | 02   | 10
    45.121    | 21.123    | 2017-03-02   | 03   | 50
    48.121    | 35.123    | 2017-03-02   | 01   | 60
    48.121    | 35.123    | 2017-03-02   | 02   | 15
    48.121    | 35.123    | 2017-03-02   | 03   | 80

Каждый файл содержит данные за разные дни и для всех комбинаций широты и долготы.

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

Итак, после просмотра всех файлов в моей папке и добавления всех данных за все дни я получил бы следующее:

Файл_45_21.csv

    longtitude| lattitude | date         | hour | value1
    ----------+-----------+--------------+------+-------
    45.121    | 21.123    | 2017-03-01   | 01   | 20
    45.121    | 21.123    | 2017-03-01   | 02   | 10
    45.121    | 21.123    | 2017-03-01   | 03   | 50
    45.121    | 21.123    | 2017-03-02   | 01   | 20
    45.121    | 21.123    | 2017-03-02   | 02   | 10
    45.121    | 21.123    | 2017-03-02   | 03   | 50

Файл_48_35.csv

    longtitude| lattitude | date         | hour | value1
    ----------+-----------+--------------+------+-------
    48.121    | 35.123    | 2017-03-01   | 01   | 60
    48.121    | 35.123    | 2017-03-01   | 02   | 15
    48.121    | 35.123    | 2017-03-01   | 03   | 80
    48.121    | 35.123    | 2017-03-02   | 01   | 60
    48.121    | 35.123    | 2017-03-02   | 02   | 15
    48.121    | 35.123    | 2017-03-02   | 03   | 80

Теоретически должно произойти следующее:

  1. Найдите различные значения для комбинации долготы и широты в данных
  2. возьмите приведенный выше массив различных значений и создайте файл для каждой комбинации и извлеките в него данные из исходных файлов на основе двух параметров (долгота и широта)

Я борюсь с тем, как начать зацикливание и извлечение данных на основе двух параметров в источнике и как «разделить» источник данных на отдельные значения комбинации параметров.


person FeodorG    schedule 05.04.2017    source источник


Ответы (2)


U-SQL не поддерживает динамический U-SQL напрямую, но для создания выходных данных можно использовать технику «сценарий сценария». Затем вы можете запустить этот вывод вручную или использовать что-то вроде Powershell или Azure Data Factory для его запуска.

Я создал простой пример на основе ваших тестовых данных, частично основанный на примере из здесь.

// Get the initial fileset
@input =
    EXTRACT longtitude float,
            lattitude float,
            date string,
            hour int,
            value1 int,
            filename string
    FROM "/input/File_201703{filename}"
    USING Extractors.Csv();


// Add int version of the long and lat columns for grouping on
@working =
    SELECT *,
           (int) longtitude AS int_long,
           (int) lattitude AS int_lat
    FROM @input;


// Work out the filenames
@filenames =
    SELECT String.Format("File {0}_{1}.csv", int_long, int_lat) AS outputFilename,
           int_long,
           int_lat
    FROM
    (
        SELECT int_long,
               int_lat
        FROM @working
        GROUP BY int_long,
                 int_lat
    ) AS x;


// Construct the dynamic usql and output it
@output =
    SELECT x.xsort, "@input = EXTRACT longtitude float, lattitude float, date string, hour int, value1 int, filename string FROM \"input/File_201703{filename}\" USING Extractors.Csv();" AS usql
   FROM ( VALUES ( 10 ) ) AS x(xsort)

    UNION ALL

    SELECT x.xsort, "@working = SELECT *, (int) longtitude AS int_long, (int) lattitude AS int_lat FROM @input;" AS usql
    FROM ( VALUES ( 20 ) ) AS x(xsort)

    UNION ALL

    SELECT 30 AS xsort, String.Format("OUTPUT (SELECT * FROM @working WHERE int_long == {0} AND int_lat == {1}) TO \"/output/{2}\" USING Outputters.Csv();", int_long, int_lat, outputFilename) AS usql
    FROM @filenames;


// Select only the usql column and sort the output
@output =
    SELECT usql
    FROM @output
ORDER BY xsort
FETCH 100;


OUTPUT @output
TO "/output/dynamic.usql"
USING Outputters.Text(delimiter : ' ', quoting : false);
person wBob    schedule 05.04.2017
comment
Привет @MichaelRys, вы видите какие-то проблемы с динамическим подходом выше? Можно ли его улучшить или это плохая идея? С благодарностью приму любой отзыв :) - person wBob; 06.04.2017
comment
Пока не запускал, вроде нормально. Возможно, я объединил создание имени файла и динамическое создание U-SQL по соображениям производительности. Вы в основном используете подход записи U-SQL с U-SQL, который я предложил выше. - person Michael Rys; 07.04.2017
comment
Мне просто интересно, стоит ли брать данные из каталога базы данных, разбивать их на разделы и записывать экспорт в CSV-файл. Будет ли это жизнеспособным решением? USQL по-прежнему можно использовать для импорта данных в таблицу и для экспорта данных в csv. - person FeodorG; 12.04.2017
comment
Да, вы могли бы это сделать. Мой вопрос будет заключаться в том, что это добавляет (например, улучшает ли это производительность, обслуживание или масштабируемость и т. д.)? Что касается меня, я добавляю таблицы ADLA, когда могу доказать, что они имеют важное значение для элементов, перечисленных выше. Если вы говорите об обычных таблицах базы данных (например, Azure SQL DB, Azure SQL Data Warehouse), то ADLA не может писать в них изначально, поэтому вам потребуется несколько дополнительных шагов — вы можете настроить что-то с Azure Data Factory для выполнения это. Я бы взвесил дополнительную сложность по сравнению с выгодой :) - person wBob; 12.04.2017
comment
@wBob: Большое спасибо! - person FeodorG; 12.04.2017
comment
Не стесняйтесь отмечать как ответ и голосовать, если это было полезно :) - person wBob; 12.04.2017

Я бы рекомендовал рассмотреть понятие наборов файлов для работы со многими файлами (см. https://msdn.microsoft.com/en-us/library/azure/mt771650.aspx) и некоторые предложения по созданию динамических выходных данных на основе значений, пока эта функция не станет доступной (см. Как мне разбить большой файл на файлы/каталоги, используя только U-SQL и определенные поля в файле? в качестве примера).

person Michael Rys    schedule 06.04.2017