首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于登录和注销时间戳的FInding活动用户使用PySpark

问基于登录和注销时间戳的FInding活动用户使用PySpark
EN

Stack Overflow用户
提问于 2022-06-30 12:22:54
回答 1查看 64关注 0票数 0

有一个包含物联网数据的数据框架。列是设备id(唯一id),连接在(时间戳),断开连接在(时间戳)。我必须让活跃的用户根据时间。首先,我们需要从连接日期和断开日期获取日期,然后创建日期列。然后我们必须创建另一个列,比如"active users“,它必须显示当天活动设备的数量。

示例:

代码语言:javascript
复制
date          active users
20-08-2021     1 (it will check connection and disconnection status in dataframe)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-01 02:20:29

我已经为您创建了示例数据和脚本。示例数据和您的尝试是您的工作。通常,在堆栈溢出上,人们不会做这样的事情,这样的问题可能会因为缺少详细信息或需要调试的脚本而被关闭。就因为我有心情..。

沿着这些路线做点什么..。

示例数据:

代码语言:javascript
复制
from pyspark.sql import functions as F
df = spark.createDataFrame(
    [(101, '2020-01-01 13:01:01', '2020-01-01 14:01:01'),
     (101, '2020-01-01 15:01:01', '2020-01-01 16:01:01'),  # same user 2nd time
     (101, '2020-01-01 17:01:01', '2020-01-02 11:01:01'),  # same user 3rd time, but overnight
     (102, '2020-01-02 05:01:01', '2020-01-02 07:01:01'),
     (103, '2020-01-02 05:01:01', '2020-01-02 07:01:01'),
     (104,                  None, '2020-01-02 07:01:01'),  # No connected_at time
     (105, '2020-01-04 10:01:01',                  None)], # No disconnected_at time
    ['device_id', 'connected_at', 'disconnected_at'])

剧本:

代码语言:javascript
复制
connection_timeout_days = -1 # If negative, not applied
logged_days_if_no_start_date = 3


# Change timestamps to dates
df = df.withColumn('connected_at', F.to_date('connected_at')) \
       .withColumn('disconnected_at', F.to_date('disconnected_at'))

# If no connected_at, subtract default number2
df = df.withColumn('connected_at', F.coalesce('connected_at',
                                   F.date_sub('disconnected_at', logged_days_if_no_start_date)))
# If no disconnected_at, add today's date or timeout days
if connection_timeout_days < 0:
    df = df.withColumn('disconnected_at', F.coalesce('disconnected_at', F.current_date()))
else:
    df = df.withColumn(
        'disconnected_at',
        F.coalesce('disconnected_at',
                   F.least(F.current_date(), F.date_add('connected_at', connection_timeout_days))))

# Create a separate df with dates for the whole period
min_date = df.agg(F.min('connected_at')).head()[0]
max_date = df.agg(F.max('disconnected_at')).head()[0]
df_dates = spark.range(1).select(
    F.explode(F.sequence(F.lit(min_date), F.lit(max_date))).alias('date')
)

# Transform original df - count distinct users per dates
df = (df
    .select('device_id',
            F.explode(F.sequence('connected_at', 'disconnected_at')).alias('date'))
    .groupBy('date')
    .agg(F.countDistinct('device_id').alias('device_distinct_count'))
)

# Join both dfs
df = df_dates.join(df, 'date', 'left') \
             .fillna(0).sort('date')

结果:

代码语言:javascript
复制
df.show()
# +----------+---------------------+
# |      date|device_distinct_count|
# +----------+---------------------+
# |2019-12-30|                    1|
# |2019-12-31|                    1|
# |2020-01-01|                    2|
# |2020-01-02|                    4|
# |2020-01-03|                    0|
# |2020-01-04|                    1|
# |2020-01-05|                    1|
# |2020-01-06|                    1|
# |2020-01-07|                    1|
# |2020-01-08|                    1|
# |2020-01-09|                    1|
# |2020-01-10|                    1|
# |2020-01-11|                    1|
# |2020-01-12|                    1|
# |2020-01-13|                    1|
# |2020-01-14|                    1|
# |2020-01-15|                    1|
# |2020-01-16|                    1|
# |2020-01-17|                    1|
# |2020-01-18|                    1|
# +----------+---------------------+
# only showing top 20 rows
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72815763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档