Pyspark - Добавить ряды по группам - PullRequest
0 голосов
/ 26 апреля 2019

В Pyspark 2.2 я, по сути, пытаюсь добавить строки по пользователю.

Если у меня есть мой основной Dataframe, который выглядит следующим образом:

main_list = [["a","bb",5], ["d","cc",10],["d","bb",11]]
main_pd = pd.DataFrame(main_list, columns = ['user',"group", 'value'])
main_df = spark.createDataFrame(main_pd)
main_df.show()

+----+-----+-----+
|user|group|value|
+----+-----+-----+
|   a|   bb|    5|
|   d|   cc|   10|
|   d|   bb|   11|
+----+-----+-----+

У меня тогда есть ключевой Dataframe, где я быхотелось бы, чтобы у каждого пользователя было каждое значение группы

Пользователь d имеет строку для группы bb и cc.Я бы хотел, чтобы у пользователя a было то же самое.

key_list = [["bb",10],["cc",17]]
key_pd = pd.DataFrame(key_list, columns = ['group', 'value'])
key_df = spark.createDataFrame(key_pd)

main_df.join(key_df, ["group"], how ="outer").show()

Но мой результат возвращает:

+-----+----+-----+-----+
|group|user|value|value|
+-----+----+-----+-----+
|   cc|   d|   10|   17|
|   bb|   a|    5|   10|
|   bb|   d|   11|   10|
+-----+----+-----+-----+

Вот схемы каждого кадра данных:

main_df.printSchema()
root
 |-- user: string (nullable = true)
 |-- group: string (nullable = true)
 |-- value: long (nullable = true)

key_df.printSchema()
root
 |-- group: string (nullable = true)
 |-- value: long (nullable = true)

По сути, я хотел бы, чтобы результат был:

+-----+----+-----+-----+
|group|user|value|value|
+-----+----+-----+-----+
|   cc|   d|   10|   17|
|   bb|   a|    5|   10|
|   cc|   a| Null|   17|
|   bb|   d|   11|   10|
+-----+----+-----+-----+

Я не думаю, что полное внешнее объединение достигнет этого с coalesce, поэтому я также экспериментировал с row_number/rank

1 Ответ

1 голос
/ 26 апреля 2019

Получите все комбинации групп пользователей с помощью cross join, затем используйте left join на maind_df для генерации пропущенных строк, а затем left join результат с key_df.

users = main_df.select("user").distinct()
groups = main_df.select("group").distinct()
user_group = users.crossJoin(groups)

all_combs = user_group.join(main_df, (main_df.user == user_group.user) & (main_df.group == user_group.group), "left").select(user_group.user,user_group.group,main_df.value)
all_combs.join(key_df, key_df.group == all_combs.group, "left").show()
...