Транспонирование данных с помощью pyspark и aws Glue

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

+-----------------+-----+------+-----+
|  Country        |Code |1969  |1979 |
+-----------------+------------------+
|  United States  | USA | 1234 | 4569|
--------------------------------------

Мне нужно перенести данные на это:

+-----------------+-----+-------+----------+
|Country          |Code | Year | Population| 
+-----------------+-------------------------
|United States.   |USA  | 1969 | 1234.     |
--------------------------------------------
|United States.   |USA  | 1970 | 4569.     |
--------------------------------------------

Я попытался использовать функцию сопоставления клеев, но это намного сложнее, чем это. Любая помощь будет принята с благодарностью.


person Ahmer Khan    schedule 12.06.2020    source источник


Ответы (1)


Я думаю, что здесь вам нужен Pyspark, эквивалентный плавлению панд:

from typing import Iterable

from pyspark.sql import functions as F
from pyspark.sql import DataFrame
def melt(
        df: DataFrame, 
        id_vars: Iterable[str], value_vars: Iterable[str], 
        var_name: str="variable", value_name: str="value") -> DataFrame:
    """Convert :class:`DataFrame` from wide to long format."""

    # Create array<struct<variable: str, value: ...>>
    _vars_and_vals = array(*(
        struct(lit(c).alias(var_name), col(c).alias(value_name)) 
        for c in value_vars))

    # Add to the DataFrame and explode
    _tmp = df.withColumn("_vars_and_vals", explode(_vars_and_vals))

    cols = id_vars + [
            col("_vars_and_vals")[x].alias(x) for x in [var_name, value_name]]
    return _tmp.select(*cols)

А потом

melt(df, id_vars=['Country', 'Code'], value_vars=['1969', '1979']
    var_name=['Year'], value_name=['Population'] ).show()
person Dee    schedule 12.06.2020