RDD की सामग्री कैसे प्रिंट करें?


124

मैं एक संग्रह की सामग्री को स्पार्क कंसोल पर प्रिंट करने का प्रयास कर रहा हूं।

मेरे पास एक प्रकार है:

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

और मैं कमांड का उपयोग करता हूं:

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

लेकिन यह छपा है:

res1: org.apache.spark.rdd.RDD [यूनिट] = MappedRDD [4] पर 19:

मैं RDD को कंसोल या डिस्क पर सहेजने के लिए कैसे लिख सकता हूं ताकि मैं इसकी सामग्री देख सकूं?


1
नमस्ते! क्या आपके द्वारा स्वीकार किए गए उत्तर पर टिप्पणी पढ़ी है? यह भ्रामक प्रतीत होता है
dk14

2
@ dk14 ने सहमति व्यक्त की, मैंने उत्तर स्वीकार कर लिया है
नीला-आकाश

RDD को द्वितीय श्रेणी के नागरिकों के रूप में पुनःप्राप्त किया जा रहा है, आपको DataFrame और showविधि का उपयोग करना चाहिए ।
थॉमस डेकाक्स

जवाबों:


235

यदि आप RDD की सामग्री देखना चाहते हैं, तो इसका उपयोग करने का एक तरीका है collect():

myRDD.collect().foreach(println)

यह एक अच्छा विचार नहीं है, हालांकि, जब आरडीडी में अरबों लाइनें हैं। take()प्रिंट आउट लेने के लिए बस कुछ लेने के लिए उपयोग करें :

myRDD.take(n).foreach(println)

1
अगर मैं HDD में सामग्री को एकल फाइल के रूप में लिखने के लिए RDD (जिसमें लाखों लाइनें हैं) पर foreach का उपयोग करता हूं, तो क्या यह बिना किसी समस्या के क्लस्टर पर काम करेगा?
शंकर

मैं saveAsTextFileRDD पर उपयोग नहीं कर रहा कारण है, मुझे RDD सामग्री को एक से अधिक फ़ाइल में लिखने की आवश्यकता है, इसीलिए मैं उपयोग कर रहा हूँforeach
शंकर

यदि आप किसी एकल फ़ाइल में सहेजना चाहते हैं, तो आप saveAsTextFile पर कॉल करने से पहले आपको RDD को एक विभाजन में ले जा सकते हैं, लेकिन फिर से यह समस्या पैदा कर सकता है। मुझे लगता है कि सबसे अच्छा विकल्प HDFS में कई फाइलों में लिखना है, फिर फ़ाइलों को मर्ज करने के लिए hdfs dfs --getmerge का उपयोग करें
Oussama

आपने कहा था कि जब RDD पर फॉर्च्यूनर का उपयोग किया जाता है तो यह ड्राइवर की रैम में बना रहेगा, क्या कथन सही है? क्योंकि जो मुझे समझ में आ रहा है वह प्रत्येक कार्यकर्ता [क्लस्टर] पर चलेगा न कि ड्राइवर पर।
शंकर

saveAsTextFile प्रति विभाजन एक फाइल लिखेगा, जो कि आप चाहते हैं (कई फाइलें)। अन्यथा जैसा कि ऊसामा सुझाव देता है, आप एक फ़ाइल प्राप्त करने के लिए rdd.coalesce (1) .saveAsTextFile () कर सकते हैं। यदि RDD के पास आपकी पसंद के लिए बहुत कम विभाजन हैं, तो आप rdd.repartition (N) .saveAsTextFile ()
foghorn

49

mapसमारोह एक है परिवर्तन है, जो कि स्पार्क वास्तव में अपने RDD का मूल्यांकन नहीं होगी जब तक आप एक को चलाने कार्रवाई उस पर।

इसे प्रिंट करने के लिए, आप उपयोग कर सकते हैं foreach(जो एक क्रिया है):

linesWithSessionId.foreach(println)

इसे डिस्क पर लिखने के लिए आप RDD APIsaveAs... से किसी एक फ़ंक्शन (स्टिल एक्शन) का उपयोग कर सकते हैं


6
शायद आपको इसका उल्लेख करने की आवश्यकता है collectताकि RDD कंसोल में मुद्रित किया जा सके।
zsxwing

1
foreachखुद आरडीडी को पहले "भौतिककृत" करेंगे और फिर printlnप्रत्येक तत्व पर चलेंगे , इसलिए collectवास्तव में यहां जरूरत नहीं है (हालांकि आप इसका उपयोग कर सकते हैं, बेशक) ...
फेड्रैगन

5
दरअसल कलेक्ट के बिना (), फॉरच्यू से पहले, मैं कंसोल पर कुछ भी नहीं देख पा रहा हूं।
विटोरियो कोज़ोलिनो

3
वास्तव में यह मेरे स्पार्क शेल में पूरी तरह से ठीक काम करता है, यहां तक ​​कि 1.2.0 में भी। लेकिन मुझे लगता है कि मुझे पता है कि यह भ्रम कहां से आता है: मूल प्रश्न ने स्पार्क कंसोल (= शेल) को आरडीडी कैसे प्रिंट किया जाए, इसलिए मैंने माना कि वह एक स्थानीय नौकरी चलाएगा, जिसमें मामला foreachठीक काम करता है। यदि आप एक क्लस्टर पर नौकरी कर रहे हैं और आप अपना आरडीडी प्रिंट करना चाहते हैं तो आपको collect(जैसा कि अन्य टिप्पणियों और उत्तरों द्वारा बताया गया है) किया जाना चाहिए ताकि यह printlnनिष्पादित होने से पहले ड्राइवर को भेजा जाए । और takeअगर आपका आरडीडी बहुत बड़ा है, तो ओसामा द्वारा सुझाए गए अनुसार उपयोग करना एक अच्छा विचार हो सकता है।
फेड्रैगन

6
उपरोक्त उत्तर बुरा है। आपको इसे अस्वीकार करना चाहिए। फ़ॉरच्यू कंसोल पर प्रिंट नहीं होगा, यह आपके कार्यकर्ता नोड पर प्रिंट होगा। यदि आपके पास केवल एक नोड है तो foreach काम करेगा। लेकिन अगर आपके पास केवल एक नोड है, तो आप स्पार्क का उपयोग क्यों कर रहे हैं? बस SQL ​​awk, या Grep, या बहुत कुछ सरल का उपयोग करें। इसलिए मुझे लगता है कि केवल मान्य उत्तर एकत्र है। अगर कलेक्शन आपके लिए बड़ा है और आप केवल एक सैंपल का उपयोग करना चाहते हैं, तो नीचे बताए अनुसार सिर या सिमिलर कार्य करें।
एशलेव

12

यदि आप इसे क्लस्टर पर चला रहे हैं तो printlnअपने संदर्भ में वापस प्रिंट नहीं करेंगे। आपको RDDअपने सत्र में डेटा लाने की आवश्यकता है । ऐसा करने के लिए आप इसे स्थानीय एरे पर मजबूर कर सकते हैं और फिर इसे प्रिंट कर सकते हैं:

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

12

आप अपने परिवर्तित कर सकते हैं RDDएक करने के लिए DataFrameतो show()यह।

// 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()

यह आपके डेटा की शीर्ष 20 लाइनें दिखाएगा, इसलिए आपके डेटा का आकार कोई समस्या नहीं होनी चाहिए।

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

1
मुझे लगता है कि यह हैimport spark.implicits._
रयान हार्टमैन

यहाँ पुस्तकालय का क्या उपयोग किया गया है? मैं स्पार्क गुंजाइश में न तो पता लगा सकता हूं toDFऔर न ही spark.implicits._
सर्गई

1

( myRDD.foreach(println)और myRDD.collect().foreach(println)न केवल 'इकट्ठा', बल्कि अन्य कार्यों के बीच) कई वास्तु अंतर हैं । एक अंतर जो मैंने देखा है जब कर रहा है myRDD.foreach(println), तो आउटपुट एक यादृच्छिक क्रम में होगा। पूर्व के लिए: यदि मेरी rdd एक टेक्स्ट फ़ाइल से आ रही है जहाँ प्रत्येक पंक्ति में एक नंबर है, तो आउटपुट का एक अलग क्रम होगा। लेकिन जब मैंने किया myRDD.collect().foreach(println), तो आदेश पाठ फ़ाइल की तरह ही रहता है।


1

अजगर में

   linesWithSessionIdCollect = linesWithSessionId.collect()
   linesWithSessionIdCollect

यह RDD की सभी सामग्रियों का प्रिंटआउट लेगा


1
धन्यवाद, लेकिन मैंने इस सवाल को टैग किया कि स्कैथ नहीं अजगर
नीला-आकाश

1
c.take(10)

और स्पार्क नया संस्करण अच्छी तरह से तालिका दिखाएगा।


1

हर बार टाइप करने के बजाय, आप कर सकते हैं;

[१] स्पार्क शेल के अंदर एक सामान्य प्रिंट विधि बनाएँ।

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

[२] या इससे भी बेहतर, अन्तर्विरोधों का उपयोग करके, आप इसकी सामग्री को छापने के लिए फ़ंक्शन को RDD वर्ग में जोड़ सकते हैं।

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

उदाहरण उपयोग:

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

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

आउटपुट:

2
6
4
8

जरूरी

यह केवल तभी समझ में आता है जब आप स्थानीय मोड में और कम मात्रा में डेटा सेट के साथ काम कर रहे हों। अन्यथा, आप या तो क्लाइंट पर परिणाम नहीं देख पाएंगे या बड़े डेटासेट परिणाम के कारण मेमोरी से बाहर निकल जाएंगे।



हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.