Сложный заказ spark dataframe

У меня есть набор данных журнала событий, например:

| patient | timestamp     | event_st       | extra_info |
| 1       | 1/1/2018 2:30 | urg_admission  | x          |
| 1       | 1/1/2018 3:00 | urg_discharge  | x          |
| 1       | 1/1/2018      | hosp_admission | y          |
| 1       | 1/10/2018     | hosp_discharge | y          | 

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

Итак, решение, которое я бы использовал в C++, - это определение сложного оператора <, где я бы использовал event_st в качестве дискриминатора при разной степени детализации по времени. Например, с отображаемыми данными события с префиксом hosp_ всегда будут располагаться после событий с префиксом urg_, если их день совпадает.

Есть ли какой-либо эквивалентный подход с использованием API DataFrame или других API Spark?

Большое тебе спасибо.

В этом случае нельзя было бы тогда упорядочить данные по 3 столбцам? Сначала на patient, затем на event_st и, наконец, на метке времени? Или у вас есть еще типы мероприятий? (в этом случае вы можете рассмотреть возможность добавления нового столбца с двумя значениями для сортировки вместо event_st).

Shaido 10.09.2018 09:04

Привет @Shaido. Спасибо за ваш комментарий. Я добавил числовой столбец event_order, который представляет собой перекодировку event_st, где я устанавливаю семантический порядок, а затем я установил порядок из трех столбцов, который вы предложили. Вроде работает, но такое ощущение, что это частичное решение ...

Juan Gonzalez 10.09.2018 10:47
1
2
45
1

Ответы 1

Один из вариантов - сначала нормализовать все временные метки к некоторой стандартной форме, такой как ddMMYY или в эпоху. Самый простой способ - использовать файл udf.

Например: если вы считаете, что все метки времени преобразованы в эпоху, ваш код будет выглядеть так:

def convertTimestamp(timeStamp:String, event_st:String) : Long = {
    if(event_st == 'urg_admission') {
    ...// Add conversion logic
    }
    if(event_st == 'hosp_admission') {
    ...// Add conversion logic
    }
     ...
}

val df = spark.read.json("/path/to/log/dataset") // I am assuming json format
spark.register.udf("convertTimestamp", convertTimestamp _)
df.createOrReplaceTempTable("logdataset")
val df_normalized = spark.sql("select logdataset.*, convertTimestamp(timestamp,event_st) as normalized_timestamp from logdataset")

После этого вы можете использовать форму нормализованного набора данных для последующей операции.

Спасибо за ваш ответ. К сожалению, сравнение немного сложнее, потому что детализация по времени варьируется: события hosp имеют детализацию по дням, а события urg - мельчайшие детали. Я знаю, что если события происходят в тот же день, события hosp должны быть упорядочены после событий urg, поэтому требуется сложное сравнение.

Juan Gonzalez 10.09.2018 09:50

Другие вопросы по теме