RDD'nin içeriği nasıl yazdırılır?


124

Bir koleksiyonun içeriğini Spark konsoluna yazdırmaya çalışıyorum.

Bir tipim var:

linesWithSessionId: org.apache.spark.rdd.RDD[String] = FilteredRDD[3]

Ve şu komutu kullanıyorum:

scala> linesWithSessionId.map(line => println(line))

Ancak bu basılmıştır:

res1: org.apache.spark.rdd.RDD [Unit] = MappedRDD [4], haritada: 19

RDD'yi konsola nasıl yazabilirim veya içeriğini görüntüleyebilmek için diske nasıl kaydedebilirim?


1
Selam! tarafınızdan kabul edilen cevap hakkındaki yorumları okudunuz mu? Yanıltıcı görünüyor
dk14

2
@ dk14 kabul etti, cevabı yeniden atadım
blue-sky

RDD ikinci sınıf vatandaşlar olarak düşürülüyor, DataFrame'i ve showyöntemi kullanmalısınız.
Thomas Decaux

Yanıtlar:


235

Bir RDD'nin içeriğini görüntülemek istiyorsanız, bir yol kullanmaktır collect():

myRDD.collect().foreach(println)

RDD'nin milyarlarca hattı varken bu iyi bir fikir değil. Çıktı take()almak için sadece birkaç tane almak için kullanın :

myRDD.take(n).foreach(println)

1
İçeriği HDFS'ye tek dosya olarak yazmak için RDD'de (milyonlarca satırı olan) foreach kullanırsam, kümede herhangi bir sorun olmadan çalışır mı?
Shankar

saveAsTextFileRDD'de kullanmamamın nedeni , RDD içeriğini birden fazla dosyaya yazmam gerekiyor, bu yüzden kullanıyorumforeach
Shankar

Tek bir dosyaya kaydetmek istiyorsanız, saveAsTextFile'ı çağırmadan önce RDD'nizi tek bir bölümde birleştirebilirsiniz, ancak bu yine sorunlara neden olabilir. Bence en iyi seçenek, HDFS'de birden fazla dosyaya yazmak, ardından dosyaları birleştirmek için hdfs dfs --getmerge kullanmaktır
Oussama

Bir RDD'de foreach kullandığınızda, sürücünün RAM'inde kalacağını söylediniz, Açıklama doğru mu? çünkü foreach'in sürücüde değil her bir işçi [küme] üzerinde çalışacağını anladım.
Shankar

saveAsTextFile, bölüm başına bir dosya yazacaktır, bu da istediğiniz şeydir (birden çok dosya). Aksi takdirde, Oussama'nın önerdiği gibi, bir dosya almak için rdd.coalesce (1) .saveAsTextFile () komutunu kullanabilirsiniz. RDD'de beğeninize göre çok az bölüm varsa, rdd.repartition (N) .saveAsTextFile ()
foghorn

49

mapİşlevi olan dönüşüm Bir bitene kadar gerçekte RDD değerlendirmek olmaz Spark demektir eylemi üzerine.

Yazdırmak için şunları kullanabilirsiniz foreach(bu bir eylemdir):

linesWithSessionId.foreach(println)

Diske yazmak saveAs...için RDD API'deki işlevlerden birini (hala eylemler) kullanabilirsiniz.


6
Belki collectRDD'nin konsolda yazdırılabilmesi için bahsetmeniz gerekiyor .
zsxwing

1
foreachkendisi önce RDD'yi "gerçekleştirecek" ve sonra printlnher eleman üzerinde çalışacaktır , bu nedenle collectburada gerçekten gerekli değildir (tabii ki kullanabilirsiniz) ...
fedragon

5
Aslında Collect () olmadan, foreach'den önce konsolda hiçbir şey göremiyorum.
Vittorio Cozzolino

3
Aslında Spark kabuğumda 1.2.0 sürümünde bile gayet iyi çalışıyor. Ama sanırım bu karışıklığın nereden geldiğini biliyorum: orijinal soru, Spark konsoluna (= kabuk) bir RDD'nin nasıl yazdırılacağını sordu, bu yüzden yerel bir işi çalıştıracağını varsaydım, bu durumda foreachiyi çalışıyor. Bir küme üzerinde bir iş çalıştırıyorsanız ve rdd'nizi yazdırmak istiyorsanız, collect(diğer yorum ve cevaplarda belirtildiği gibi) printlnçalıştırılmadan önce sürücüye gönderilmesi için yapmanız gerekir . takeRDD'niz çok büyükse, Oussama tarafından önerildiği gibi kullanmak iyi bir fikir olabilir.
fedragon

6
Yukarıdaki cevap kötü. Kabul etmemelisin. Foreach konsola yazdırmayacak, çalışan düğümlerinize yazdıracaktır. Tek bir düğümünüz varsa foreach çalışacaktır. Ancak tek bir düğümünüz varsa, neden kıvılcım kullanıyorsunuz? Sadece SQL awk veya Grep veya çok daha basit bir şey kullanın. Bu yüzden tek geçerli cevabın toplamak olduğunu düşünüyorum. Toplama sizin için büyükse ve yalnızca örnek bir kullanım istiyorsanız, aşağıda açıklandığı gibi alma veya baş veya benzeri işlevleri kullanın.
eshalev

12

Bunu bir küme üzerinde çalıştırıyorsanız println, içeriğinize geri yazdırmaz. RDDVerileri oturumunuza getirmeniz gerekir . Bunu yapmak için onu yerel diziye zorlayabilir ve sonra yazdırabilirsiniz:

linesWithSessionId.toArray().foreach(line => println(line))

12

Kendinizi RDDbir DataFramesonra show()ona dönüştürebilirsiniz .

// For implicit conversion from RDD to DataFrame
import spark.implicits._

fruits = sc.parallelize([("apple", 1), ("banana", 2), ("orange", 17)])

// convert to DF then show it
fruits.toDF().show()

Bu, verilerinizin ilk 20 satırını gösterecektir, bu nedenle verilerinizin boyutu bir sorun olmamalıdır.

+------+---+                                                                    
|    _1| _2|
+------+---+
| apple|  1|
|banana|  2|
|orange| 17|
+------+---+

1
Sanırım öyleimport spark.implicits._
Ryan Hartman

Burada kullanılan kütüphane nedir? Ne kıvılcım ne toDFde spark.implicits._kıvılcım kapsamında tespit edemiyorum .
Sergii

1

Muhtemelen myRDD.foreach(println)ve arasında pek çok mimari fark vardır myRDD.collect().foreach(println)(sadece 'toplamak' değil, aynı zamanda diğer eylemler). Gördüğüm farklardan biri, myRDD.foreach(println)çıktıların rastgele bir sırada olacağıdır. Örneğin: rdd her satırın bir sayıya sahip olduğu bir metin dosyasından geliyorsa, çıktının farklı bir sırası olacaktır. Ama yaptığım zaman myRDD.collect().foreach(println), düzen tıpkı metin dosyası gibi kalıyor.


1

Python'da

   linesWithSessionIdCollect = linesWithSessionId.collect()
   linesWithSessionIdCollect

Bu, RDD'nin tüm içeriğini yazdıracaktır.


1
Teşekkürler ama bu soruyu scala değil python ile etiketledim
blue-sky

1
c.take(10)

ve Spark'ın yeni sürümü tabloyu güzel bir şekilde gösterecek.


1

Her seferinde yazmak yerine şunları yapabilirsiniz;

[1] Spark Shell içinde genel bir yazdırma yöntemi oluşturun.

def p(rdd: org.apache.spark.rdd.RDD[_]) = rdd.foreach(println)

[2] Veya daha da iyisi, implicits kullanarak, içeriğini yazdırmak için işlevi RDD sınıfına ekleyebilirsiniz.

implicit class Printer(rdd: org.apache.spark.rdd.RDD[_]) {
    def print = rdd.foreach(println)
}

Örnek kullanım:

val rdd = sc.parallelize(List(1,2,3,4)).map(_*2)

p(rdd) // 1
rdd.print // 2

Çıktı:

2
6
4
8

Önemli

Bu, yalnızca yerel modda ve az miktarda veri kümesiyle çalışıyorsanız anlamlıdır. Aksi takdirde, sonuçları istemcide göremezsiniz veya büyük veri kümesi sonucu nedeniyle belleğiniz tükenir.



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.