Группировка людей по увлечениям

#apache-spark #graph #cluster-analysis #spark-graphx

#apache-spark #График #кластерный анализ #spark-graphx

Вопрос:

Я пытался решить эту проблему, но не могу связать ее с каким-либо решением. У меня есть следующий набор данных:

 [
  {"name": "sam", "hobbies": ["Books", "Music", "Gym"]},
  {"name": "Steve", "hobbies": ["Books", "Swimming"]},
  {"name": "Alex", "hobbies": ["Gym", "Music"]}
]
  

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

 [
  {"names": ["sam", "Steve"], "hobbies": ["Books"]},
  {"names": ["sam", "Alex"], "hobbies": ["Music", "Gym"]},
  {"names": ["Steve"], "hobbies": ["Swimming"]}
]
  

Это большой набор данных, поэтому я пытался использовать Spark.

Вещи, которые я пробовал:

  • Изначально я пытался понять, не проблема ли это с графом, и я могу использовать что-то вроде сильно связанных компонентов, но, похоже, это не решит проблему.

  • Каждая строка вывода выглядит как двудольный граф, но я не смог найти способ сгенерировать и его.

  • Другим подходом была кластеризация, но я думал, что она не будет детерминированной. Пожалуйста, дайте мне знать, если я ошибаюсь. Я не слишком хорошо знаком с этим.

Дайте мне знать, если я упускаю что-то очевидное здесь. Спасибо.

Комментарии:

1. вы можете использовать explode хобби, а затем использовать groupBy amp; collect list в столбцах имя и хобби.

2. @Srinivas да, но тогда как мне найти частичные списки имен, которые являются общими увлечениями?

Ответ №1:

Проверьте приведенный ниже код.

 scala> df.show(false)
 ------------------- ----- 
|hobbies            |name |
 ------------------- ----- 
|[Books, Music, Gym]|sam  |
|[Books, Swimming]  |Steve|
|[Gym, Music]       |Alex |
 ------------------- ----- 
  

Использование groupBy amp; collect_list

  1. Группировать hobbies и собирать список names
  2. Группировать names и собирать список hobbies
 scala> :paste
// Entering paste mode (ctrl-D to finish)

df
.withColumn("hobbies",explode($"hobbies"))
.groupBy($"hobbies").agg(collect_list($"name").as("names")) // For Hobbies List
.groupBy($"name").agg(collect_list($"hobbies").as("hobbies")) // For Name List
.select(collect_list(to_json(struct($"hobbies",$"names"))).as("data")) // Final Json Output
.show(false)


// Exiting paste mode, now interpreting.

 -------------------------------------------------------------------------------------------------------------------------------------------- 
|data                                                                                                                                        |
 -------------------------------------------------------------------------------------------------------------------------------------------- 
|[{"hobbies":["Swimming"],"names":["Steve"]}, {"hobbies":["Books"],"names":["sam","Steve"]}, {"hobbies":["Music","Gym"],"names":["sam","Alex"]}]|
 -------------------------------------------------------------------------------------------------------------------------------------------- 

  

Форматированный вывод

 [
  { "hobbies": ["Swimming"],"names": ["Steve"]},
  {"hobbies": ["Books"],"names": ["sam","Steve"]},
  {"hobbies": ["Music","Gym"],"names": ["sam","Alex"]}
]
  

Комментарии:

1. Я предполагаю, что вторая groupBy находится в $ «names», выводе agg первой groupBy. Я думаю, это сработает. Я попробую. Спасибо