задний план
Любой, кто выполнял работу по очистке данных ETL, знает, что преобразование строк и столбцов является распространенным требованием очистки данных. В разных языках программирования существуют разные методы реализации, например использование case+group в SQL или использование компонентов перетаскивания в языке M Power BI. Сегодня мне просто нужно обработать преобразование строк и столбцов данных в pyspark, поэтому я записываю этот метод.
Прежде всего, что это такое?преобразование строки в столбец, потому что это название не очень единообразно, некоторые места называются транспозицией, некоторые места называются перспективой и так далее. Возьмем в качестве примера следующий рисунок и определим его следующим образом:
- От левого к правому, это называетсяВращаться
- НаоборотРазвернуть
Реализация искры
Построить выборочные данные
Сначала мы строимРядФормат для сохранения набора данных
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('JupyterPySpark').enableHiveSupport().getOrCreate()
import pyspark.sql.functions as F
# 原始数据
df = spark.createDataFrame([('2018-01','项目1',100), ('2018-01','项目2',200), ('2018-01','项目3',300),
('2018-02','项目1',1000), ('2018-02','项目2',2000), ('2018-03','项目x',999)
], ['年月','项目','收入'])
Пример данных выглядит следующим образом: мы видим, что каждый элемент имеет только одну строку записей в указанном месяце, и элементы разрежены. То есть не каждый элемент будет появляться в каждом месяце, напримерпункт 2появляется только в2018-01среди.
+-------+---+----+
| 年月| 项目| 收入|
+-------+---+----+
|2018-01|项目1| 100|
|2018-01|项目2| 200|
|2018-01|项目3| 300|
|2018-02|项目1|1000|
|2018-02|项目2|2000|
|2018-03|项目x| 999|
+-------+---+----+
Вращаться
Перспективная операция проста и пряма, логика следующая
- Группировать по полям, которые не нужно преобразовывать, в данном случае этогоды;
- Используйте функцию поворота для поворота, и вы можете указать второй параметр во время процесса поворота, чтобы явно указать, какие элементы данных использовать;
- Суммировать числовые поля, в данном случаедоход;
код показывает, как показано ниже
df_pivot = df.groupBy('年月')\
.pivot('项目', ['项目1','项目2','项目3','项目x'])\
.agg(F.sum('收入'))\
.fillna(0)
Результат выглядит следующим образом
+-------+----+----+---+---+
| 年月| 项目1| 项目2|项目3|项目x|
+-------+----+----+---+---+
|2018-03| 0| 0| 0|999|
|2018-02|1000|2000| 0| 0|
|2018-01| 100| 200|300| 0|
+-------+----+----+---+---+
Развернуть
Spark не предоставляет встроенных функций для реализации операций разворота, но мы можем использовать Spark SQL для предоставленияstackФункция для косвенной реализации требования. Есть несколько моментов, на которые стоит обратить особое внимание:
- Выполнение фрагментов SQL в Spark с помощью selectExpr;
- Если имя поля на китайском языке, используйте обратные кавычки **`** для переноса поля;
код показывает, как показано ниже
df_pivot.selectExpr("`年月`",
"stack(4, '项目1', `项目1`,'项目2', `项目2`, '项目3', `项目3`, '项目x', `项目x`) as (`项目`,`收入`)")\
.filter("`收入` > 0 ")\
.orderBy(["`年月`", "`项目`"])\
.show()
Результат выглядит следующим образом
+-------+---+----+
| 年月| 项目| 收入|
+-------+---+----+
|2018-01|项目1| 100|
|2018-01|项目2| 200|
|2018-01|项目3| 300|
|2018-02|项目1|1000|
|2018-02|项目2|2000|
|2018-03|项目x| 999|
+-------+---+----+