Разбивка строк в фрейме данных Pyspark

У меня есть фрейм данных PySpark в этом формате:

 dbn      |       bus      | subway   | score
----------|----------------|----------|--------
XYZ12     | B1, B44, B66   | A, C     | 59
ZYY3      | B8, B3, B7     | J, Z     | 66

То, что я хочу сделать, это иметь возможность прикрепить столбец оценка к каждому отдельному автобусу и линии метро, однако я хочу работать на одной колонке в то время, так что я начну с автобуса. В конечном счете, я хочу, чтобы мой фрейм данных выглядел так (когда я работаю с колонкой шины)

dbn      | bus       | subway  | score
---------|-----------|---------|-------
XYZ12    | B1        | A, C    | 59
XYZ12    | B44       | A, C    | 59
XYZ12    | B66       | A, C    | 59
ZYY3     | B8        | J, Z    | 66
ZYY3     | B3        | J, Z    | 66
ZYY3     | B7        | J, Z    | 66

Как бы я это сделал?

1 ответ

  1. Можно explodeиспользовать функцию, которая ожидает столбец arrayили mapстолбец в качестве входных данных. Если busэто строка, вы можете использовать функции обработки строк , напримерsplit, чтобы разбить ее на части. Предположим этот сценарий:

    df = sc.parallelize([
        ("XYZ12", "B1, B44, B66", "A, C", 59),
        ("ZYY3 ", "B8, B3, B7", "J, Z", 66)
    ]).toDF(["dbn", "bus", "subway", "score"])
    

    Первый импорт необходимых функций:

    from pyspark.sql.functions import col, explode, split, trim
    

    добавить столбец:

    with_bus_exploded = df.withColumn("bus", explode(split("bus", ",")))
    

    и trimведущие / отставая космосы:

    with_bus_trimmed = with_bus_exploded.withColumn("bus", trim(col("bus")))
    

    Наконец, результат:

    +-----+---+------+-----+
    |  dbn|bus|subway|score|
    +-----+---+------+-----+
    |XYZ12| B1|  A, C|   59|
    |XYZ12|B44|  A, C|   59|
    |XYZ12|B66|  A, C|   59|
    |ZYY3 | B8|  J, Z|   66|
    |ZYY3 | B3|  J, Z|   66|
    |ZYY3 | B7|  J, Z|   66|
    +-----+---+------+-----+