2016-04-07 2 views
2

Как я могу использовать API-интерфейс SPARK DataFrame для группировки по идентификатору, вычисления всех комбинаций значений внутри группы и создания единого выходного блока данных?API-интерфейс Spark Dataframe: группировка по идентификаторам и комбинациям вычислений

Пример:

val testSchema = StructType(Array(
    StructField("id", IntegerType), 
    StructField("value", StringType))) 

val test_rows = Seq(
    Row(1, "a"), 
    Row(1, "b"), 
    Row(1, "c"), 
    Row(2, "a"), 
    Row(2, "d"), 
    Row(2, "e") 
) 
val test_rdd = sc.parallelize(test_rows) 
val test_df = sqlContext.createDataFrame(test_rdd, testSchema) 

Ожидаемый результат:

1 a b 
1 a c 
1 b c 
2 a d 
2 a e 
2 d e 

Лучшее решение до сих пор:

Выполните автообъединение, фильтр на ид равенства и устранить равные значения

val result = test_df.join(
    test_df.select(test_df.col("id").as("r_id"), test_df.col("value").as("r_value")), 
    ($"id" === $"r_id") and ($"value" !== $"r_value")).select("id", "value", "r_value") 


+---+-----+-------+ 
| id|value|r_value| 
+---+-----+-------+ 
| 1| a|  b| 
| 1| a|  c| 
| 1| b|  a| 
| 1| b|  c| 
| 1| c|  a| 
| 1| c|  b| 
| 2| a|  d| 
| 2| a|  e| 
| 2| d|  a| 
| 2| d|  e| 
| 2| e|  a| 
| 2| e|  d| 
+---+-----+-------+ 

Оставаясь проблема: как избавиться от повторяющихся наборов, например, (а, Ь) и (Ь, а) при выполнении присоединиться?

+1

В этом случае лучше использовать 'RDD' вместо' DataFame', прочитать это [Функция агрегирования Spark DataFrame] (http://stackoverflow.com/questions/33899977/spark-dataframe-custom-aggregation- функция-to-sum-a-column-of-vector), и вы заметите, почему. –

ответ

1

У вас есть заказ на объекты в поле значений? Если это так, кажется, что вы можете просто присоединиться к кадру данных сами по себе, требуя, чтобы идентификаторы были идентичными, а значение из левой таблицы было меньше значения из правой таблицы.

[edit] Если у вас нет заказа, и у вас достаточно нескольких значений для одного идентификатора, другое решение - использовать groupByKey, а затем создать все комбинации из результирующей последовательности, что можно сделать проще, чем создавать все пар, а затем только половина. (Если вы используете Scala, например, я полагаю, что : combination функция [doc] сделает то, что вам нужно.) Это будет намного хуже, чем подход самоподключения для большинства наборов данных.

+0

К сожалению, значения не являются числовыми ... поэтому я должен исключить множество дубликатов на этапе постпроцессинга. – behas

+0

@behas: им не нужно быть числовым, чтобы иметь заказ. Например, если это строки, у вас есть лексикографическое упорядочение, которое вы можете использовать для сравнения. '" a "<" b "' будет разрешено для 'true' и' "b" <"a" 'будет разрешено' false'. Если они являются объектами с более сложной структурой, также будет работать сравнение уникальных идентификаторов или строковых меток. –

+0

без лексикографического заказа ... значения - это хеши – behas

Смежные вопросы