PySpark - Выберите пользователей, которых видели 3 дня в неделю, 3 недели в месяц. - PullRequest
0 голосов
/ 14 января 2019

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

У меня есть фрейм данных

|user_id| action | day | week |
------------------------------
| d25as | AB     | 2   | 1    |
| d25as | AB     | 3   | 2    |
| d25as | AB     | 5   | 1    | 
| m3562 | AB     | 1   | 3    |
| m3562 | AB     | 7   | 1    |
| m3562 | AB     | 9   | 1    |
| ha42a | AB     | 3   | 2    |
| ha42a | AB     | 4   | 3    |
| ha42a | AB     | 5   | 1    |

Я хочу создать фрейм данных с пользователями, которые кажутся как минимум 3 дня в неделю для как минимум 3 недели в месяц . Столбец «день» изменяется от 1 до 31, а столбец «неделя» - от 1 до 4.

Я думал о том, как это сделать:

split dataframe into 4 dataframes for each week
for every week_dataframe count days seen per user. 
count for every user how many weeks with >= 3 days they were seen.
only add to the new df the users seen for >= 3 such weeks. 

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

Ответы [ 2 ]

0 голосов
/ 15 января 2019

@ eakotelnikov правильно.

Но если кто-то сталкивается с ошибкой

NameError: имя 'countDistinct' не определено

, затем, пожалуйста, используйте нижеприведенное заявление для выполнения решения eakotelnikov

from pyspark.sql.functions import *

Добавление другого решения для этой проблемы

tdf.registerTempTable("tbl")

outdf = spark.sql(""" 
select user_id , count(*) as weeks_per_user from
( select user_id , week , count(*) as days_per_week 
  from tbl 
  group by user_id , week  
  having count(*) >= 3
 ) x
group by user_id
having count(*) >= 3
""")

outdf.show()
0 голосов
/ 14 января 2019

Я предлагаю использовать функцию groupBy для выбора пользователей с селектором where:

df.groupBy('user_id', 'week')\
.agg(countDistinct('day').alias('days_per_week'))\
.where('days_per_week >= 3')\
.groupBy('user_id')\
.agg(count('week').alias('weeks_per_user'))\
.where('weeks_per_user >= 3' )
...