Вопрос или проблема
У меня есть столбец в таблице со строками переменной длины:
|value |
|-------------|
|abcdefgh |
|1234567891011|
Мне нужно разбить строки на массивы строк, где каждая строка длиной 2 (за исключением последней строки в случае нечетного числа символов). Вот так:
|value |split_value |
|-------------|---------------------------|
|abcdefgh |[ab, cd, ef, gh, ] |
|1234567891011|[12, 34, 56, 78, 91, 01, 1]|
Это работает в pyspark:
# Пример данных
data = [("abcdefgh",), ("1234567891011",)]
df = spark.createDataFrame(data, ["value"])
# Регистрируем DataFrame как временный вид
df.createOrReplaceTempView("strings")
# Используем Spark SQL, чтобы добавить разделитель каждые 2 символа, а затем разбить строку
result = spark.sql("""
SELECT
value,
split(regexp_replace(value, '(.{2})', '$1,'), ',') AS split_value
FROM strings
""")
# Показываем результат
result.show(truncate=False)
… давая ожидаемую результирующую таблицу выше.
Однако, когда я выполняю точно такое же SQL выражение в ячейке SQL в ноутбуке Databricks, я получаю массив пустых строк:
%sql
SELECT
value,
split(regexp_replace(value, '(.{2})', '$1,'), ',') AS split_value
FROM strings
|value |split_value |
|-------------|----------------------------|
|abcdefgh |["", "", "", "", ] |
|1234567891011|["", "", "", "", "", "", ""]|
Также я получаю это предупреждение:
Как я могу достичь желаемого результата в SQL на Databricks?
Добавляю свой комментарий как ответ. Я редко, если вообще когда-либо, использую regexp_replace, но это, похоже, работает. Прошу прощения за отсутствие дополнительной информации здесь.
В версии SQL попробуйте изменить это:
regexp_replace(value, '(.{2})', '$1,')
на это:
regexp_replace(value, '(.{2})', '$\1,')
Ответ или решение
Чтобы разделить строку в массив строк одинаковой длины с использованием чистого SQL в Databricks, вам необходимо использовать функцию regexp_replace
, уточнив регулярное выражение, а также метод split
для получения итогового массива. Ваша задача состоит в том, чтобы создать массив длиной 2 для каждой строки, учитывая, что последняя строка может содержать менее 2 символов, если ее длина нечетная.
Подробный подход к решению задачи
-
Регулярное выражение: Правильное постоянное выражение необходимо для выполнения замены. Мы используем
(.{2})
для захвата всех пар символов. Однако в SQL в Databricks вам нужно будет использовать обратные ссылки, что требует некоторого изменения в регулярном выражении. -
Запись SQL запроса: Давайте рассмотрим, как записать SQL код. Вы заменяете ‘(.{2})’ на ‘$\1,’ вместо ‘$1,’ для правильного формирования строк.
Пример выполнения
Рассмотрим следующий SQL-запрос, который выполняет требуемую задачу:
-- Создание временной таблицы
CREATE OR REPLACE TEMP VIEW strings AS
SELECT 'abcdefgh' AS value UNION ALL
SELECT '1234567891011' AS value;
-- Запрос для разделения строки на массив
SELECT
value,
split(regexp_replace(value, '(.{2})', '$\\1,'), ',') AS split_value
FROM strings;
Описание выполнения запроса
-
Создание временной таблицы: Временная таблица
strings
создается с использованием двух строк. В этом случае генерируются строки с различной длиной. -
Функция regexp_replace: Используется для замены каждой пары символов на саму пару, за которой следует запятая. Изменение обратной ссылки со ‘$1,’ на ‘$\1,’ позволяет избежать пустых строк в выходных данных.
-
Функция split: После преобразования строки, функция
split
делит полученную строку по запятой, формируя массив строк.
Ожидаемый результат
После выполнения вышеизложенного запроса вы получите следующий результат:
|value |split_value |
|-------------|---------------------------|
|abcdefgh |[ab, cd, ef, gh] |
|1234567891011|[12, 34, 56, 78, 91, 01, 1]|
Заключение
Данный подход позволяет успешно разбивать строки переменной длины на массив строк фиксированной длины в среде Databricks с использованием SQL. Убедитесь, что вы используете правильные символы для обратных ссылок в регулярных выражениях, чтобы избежать получения пустых строк в результатах. Это позволяет достичь желаемого результата, как в примере PySpark, обеспечивая, что вывод соответствует поставленной задаче.