2016-04-07 22 views
2

SPARK DataFrame API'sını kimliğe göre gruplandırmak, bir gruptaki tüm değer kombinasyonlarını hesaplamak ve tek bir çıktı veri çerçevesi oluşturmak için nasıl kullanabilirim?Spark Dataframe API'sı: grup kimliği ve bilgi işlem kombinasyonları

Örnek:

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) 

Beklenen çıkış: Şimdiye kadar

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

En çözüm: katılmak

gerçekleştirin öz, id eşitliği filtre ve sorunu Kalan eşitleyen

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| 
+---+-----+-------+ 

ortadan kaldırmak: ne kadar yinelenen setleri, örneğin, (a, b) ve (b, a) birleştirme gerçekleştirirken ortadan kaldırmak için?

+1

Bu durumda 'DataFame' yerine bir' RDD 'kullanmak daha iyidir, bunu okuyun [Spark DataFrame Toplama İşlevi] (http://stackoverflow.com/questions/33899977/spark-dataframe-customagroupregation- -sistemi-sütun-of-vektörleri) ve neden olduğunu göreceksiniz. –

cevap

1

Değer alanındaki nesnelere ilişkin bir siparişiniz var mı? Eğer öyleyse, sadece veri çerçevesine kendi başına katılabiliyor gibi görünüyorsunuz, aynı zamanda, kimliklerin aynı olması ve sol tablodaki değerin sağdaki değerden daha az olması gerekir.

[değiştir] Siparişiniz yoksa ve kimlik başına yeterince az değeriniz varsa, başka bir çözüm de groupByKey kullanmaktır ve daha sonra tüm dizileri oluşturmaktan daha fazlasını yapabilirsiniz. çiftleri ve daha sonra sadece yarım tutmak. (Örneğin, Scala kullanıyorsanız, Seq'un combination işlevinin [doc] işlevine gereksinim duyacağına inanıyorum.) Bu, çoğu veri kümesi için kendi kendine katılma yaklaşımından çok daha kötü performans gösterecektir.

+0

Maalesef, değerler sayısal değil ... bu yüzden bir sonraki işlem adımında set çoğaltmaları kaldırmalıyım sanırım. – behas

+0

@behas: Sipariş vermek için sayısal olmaları gerekmez. Dizeleri varsa, örneğin, karşılaştırmalar için kullanabileceğiniz sözcükbilgisel bir sıralamaya sahipsiniz. "a" <"b", "true" ve "b" <"a" ifadelerini "false" olarak çözecektir. Daha karmaşık yapıya sahip nesnelerse, benzersiz kimlikleri veya dize etiketlerini karşılaştırmak da işe yarayacaktır. –

+0

sözlüksel bir sıralama yok ... değerler hashes – behas