Фрейм данных Pyspark Pivot в зависимости от состояния - PullRequest
0 голосов
/ 10 мая 2018

У меня есть кадр данных в pyspark, как показано ниже.

df.show()

+---+-------+----+
| id|   type|s_id|
+---+-------+----+
|  1|    ios|  11|
|  1|    ios|  12|
|  1|    ios|  13|
|  1|    ios|  14|
|  1|android|  15|
|  1|android|  16|
|  1|android|  17|
|  2|    ios|  21|
|  2|android|  18|
+---+-------+----+

Теперь из этого фрейма данных я хочу создать другой фрейм данных, повернув его.

df1.show()
+---+-----+-----+-----+---------+---------+---------+
| id| ios1| ios2| ios3| android1| android2| android3|
+---+-----+-----+-----+---------+---------+---------+
|  1|   11|   12|   13|       15|       16|       17|
|  2|   21| Null| Null|       18|     Null|     Null|
+---+-----+-----+-----+---------+---------+---------+

Здесь мне нужно рассмотреть условие, что для каждого Id, хотя их будет больше, чем 3 types, я хочу рассмотреть только 3 or less than 3.

Как я могу это сделать?

Редактировать

new_df.show()

+---+-------+----+
| id|   type|s_id|
+---+-------+----+
|  1|    ios|  11|
|  1|    ios|  12|
|  1|       |  13|
|  1|       |  14|
|  1|andriod|  15|
|  1|       |  16|
|  1|       |  17|
|  2|andriod|  18|
|  2|    ios|  21|
+---+-------+----+

Результат, который я получаю, ниже

+---+----+----+----+--------+----+----+
| id|   1|   2|   3|andriod1|ios1|ios2|
+---+----+----+----+--------+----+----+
|  1|  13|  14|  16|      15|  11|  12|
|  2|null|null|null|      18|  21|null|
+---+----+----+----+--------+----+----+

То, что я хочу, это

+---+--------+--------+--------+----+----+----+
|id |android1|android2|android3|ios1|ios2|ios3|
+---+--------+--------+--------+----+----+----+
|1  |15      |    null|    null|  11|  12|null|
|2  |18      |    null|    null|  21|null|null|
+---+--------+--------+--------+----+----+----+

1 Ответ

0 голосов
/ 10 мая 2018

Используя следующую логику, вы получите желаемый результат.

Функция

Window используется для генерации номера строки для каждой группы id и type, упорядоченной по s_id. Сгенерированный номер строки используется для filter и concat с type. Затем, наконец, группировка и поворот должны дать вам желаемый результат

from pyspark.sql import Window 
windowSpec = Window.partitionBy("id", "type").orderBy("s_id")

from pyspark.sql import functions as f

df.withColumn("ranks", f.row_number().over(windowSpec))\
    .filter(f.col("ranks") < 4)\
    .withColumn("type", f.concat(f.col("type"), f.col("ranks")))\
    .drop("ranks")\
    .groupBy("id")\
    .pivot("type")\
    .agg(f.first("s_id"))\
    .show(truncate=False)

что должно дать вам

+---+--------+--------+--------+----+----+----+
|id |android1|android2|android3|ios1|ios2|ios3|
+---+--------+--------+--------+----+----+----+
|1  |15      |16      |17      |11  |12  |13  |
|2  |18      |null    |null    |21  |null|null|
+---+--------+--------+--------+----+----+----+

ответ за отредактированную часть

Вам просто нужен дополнительный фильтр как

df.withColumn("ranks", f.row_number().over(windowSpec)) \
    .filter(f.col("ranks") < 4) \
    .filter(f.col("type") != "") \
    .withColumn("type", f.concat(f.col("type"), f.col("ranks"))) \
    .drop("ranks") \
    .groupBy("id") \
    .pivot("type") \
    .agg(f.first("s_id")) \
    .show(truncate=False)

что даст вам

+---+--------+----+----+
|id |andriod1|ios1|ios2|
+---+--------+----+----+
|1  |15      |11  |12  |
|2  |18      |21  |null|
+---+--------+----+----+

Теперь в этом фрейме данных отсутствуют android2, android3 and ios3 столбцы. Потому что их нет в ваших обновленных входных данных. Вы можете добавить их, используя withColumn API и заполнить нулевыми значениями

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...