Как мне сложить определенное значение за определенный день недели?

У меня есть дата-фрейм телефонных звонков, который содержит метку времени и продолжительность звонка. Как бы я суммировал общую продолжительность каждого дня для всех телефонных звонков? Метка времени - это строка, поэтому у меня возникли проблемы с ее анализом до фактической даты. Я не уверен, имеет ли спарк поддержку временных меток.

Таблица данных

  timestamp   |  duration
1414592818364 |   210
1414575535061 |   110
1411328461890 |   140
1434606396339 |   90

1 ответ

Решение

Вы можете использовать UDF для анализа меток времени. Ниже вы можете найти решение Python, но сделать то же самое довольно просто, используя другой поддерживаемый язык:

С сырым SQL:

from datetime import datetime

df = sqlContext.createDataFrame(sc.parallelize([
    {'timestamp': 1414592818364, 'duration': 210},
    {'timestamp': 1414575535061, 'duration': 110},
    {'timestamp': 1411328461890, 'duration': 140},
    {'timestamp': 1434606396339, 'duration': 90}]))


def parse_timestamp(tm):
    dt = datetime.fromtimestamp(tm / 1000)
    return '{0}-{1}-{2}'.format(dt.year, dt.month, dt.day)

sqlContext.registerFunction('parse_timestamp', parse_timestamp)

df.registerTempTable('df')

query = '''
    SELECT parse_timestamp(timestamp) AS date, sum(duration) AS total_durtaion
    FROM df GROUP BY parse_timestamp(timestamp)'''

(sqlContext
    .sql(query)
    .show())

или SQL DSL:

from pyspark.sql.functions import udf
from pyspark.sql.types import StringType

(df
    .withColumn('date', udf(parse_timestamp, StringType())(df.timestamp))
    .select('date', 'duration')
    .groupby('date')
    .sum()
    .show())

РЕДАКТИРОВАТЬ:

Начиная с Spark 1.5 нет необходимости в кастомном udf.

from pyspark.sql.functions import from_unixtime, col, sum

(df
  .groupBy(from_unixtime(df.timestamp / 1000, "yyyy-MM-dd").alias("date"))
  .agg(sum(col("duration"))))
Другие вопросы по тегам