अपाचे स्पार्क में सूची के रूप में डेटाफ्रेम के कॉलम मान निकालें


86

मैं डेटा फ्रेम के एक स्ट्रिंग कॉलम को एक सूची में बदलना चाहता हूं। मुझे DataframeAPI से क्या मिल सकता है RDD है, इसलिए मैंने इसे पहले RDD में बदलने की कोशिश की, और फिर toArrayRDD में फ़ंक्शन लागू किया । इस स्थिति में, लंबाई और SQL ठीक काम करते हैं। हालाँकि, मुझे RDD से जो परिणाम मिला है, उसमें इस तरह के हर तत्व के चारों ओर चौकोर कोष्ठक हैं [A00001]। मैं सोच रहा था कि एक कॉलम को सूची में बदलने का एक उपयुक्त तरीका है या वर्ग कोष्ठक को हटाने का तरीका है।

किसी भी सुझाव की सराहना की जाएगी। धन्यवाद!


जवाबों:


117

यह एकल सूची वाले संग्रह को वापस करना चाहिए:

dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()

मैपिंग के बिना, आपको बस एक पंक्ति वस्तु मिलती है, जिसमें डेटाबेस से प्रत्येक कॉलम होता है।

ध्यान रखें कि इससे आपको किसी भी प्रकार की सूची मिल जाएगी। Result यदि आप परिणाम प्रकार निर्दिष्ट करना चाहते हैं, तो आप r => r(0).asInstanceOf[YOUR_TYPE]मानचित्रण में .asInstanceOf [your_TYPE] का उपयोग कर सकते हैं

पुनश्च स्वचालित रूपांतरण के कारण आप .rddभाग को छोड़ सकते हैं ।


3
किसी अजीब कारण से यह दूसरे तरीके से काम करता है (स्पार्क 2.1.0) collect().map(r => r(0))- क्या इस आदेश का कोई नुकसान है?
बोर्न

धीमा हो सकता है - आपका समाधान पहले ड्राइवर पर सभी डेटा एकत्र करता है, और उसके बाद यह ड्राइवर पर मैपिंग करता है (निष्पादक सहायता के बिना), केवल एकल चालक की प्रसंस्करण शक्ति का उपयोग करके।
नीमच

72

स्पार्क 2.x और स्काला 2.11 के साथ

मैं विशिष्ट कॉलम के मानों को सूची में बदलने के लिए 3 संभावित तरीके सोचता हूं।

सभी दृष्टिकोणों के लिए सामान्य कोड स्निपेट

import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder.getOrCreate    
import spark.implicits._ // for .toDF() method

val df = Seq(
    ("first", 2.0),
    ("test", 1.5), 
    ("choose", 8.0)
  ).toDF("id", "val")

दृष्टिकोण १

df.select("id").collect().map(_(0)).toList
// res9: List[Any] = List(one, two, three)

अब क्या हुआ? हम ड्राइवर के साथ डेटा एकत्र कर रहे हैं collect()और प्रत्येक रिकॉर्ड से तत्व शून्य उठा रहे हैं।

यह इसे करने का एक उत्कृष्ट तरीका नहीं हो सकता है, आइए इसे अगले दृष्टिकोण के साथ सुधारें।


दृष्टिकोण २

df.select("id").rdd.map(r => r(0)).collect.toList 
//res10: List[Any] = List(one, two, three)

यह कैसे बेहतर है? हमने एकल चालक के बजाय श्रमिकों के बीच मानचित्र परिवर्तन भार वितरित किया है।

मुझे पता rdd.map(r => r(0))है कि आप सुरुचिपूर्ण नहीं लगते। तो, चलिए इसे अगले दृष्टिकोण से संबोधित करते हैं।


दृष्टिकोण ३

df.select("id").map(r => r.getString(0)).collect.toList 
//res11: List[String] = List(one, two, three)

यहां हम DataFrame को RDD में परिवर्तित नहीं कर रहे हैं। mapयह देखें कि DataFrame में एनकोडर मुद्दों के कारण पिछले दृष्टिकोण के रूप में r => r(0)(या _(0)) को स्वीकार नहीं किया जाएगा । तो अंत में उपयोग कर रहा है r => r.getString(0)और यह स्पार्क के अगले संस्करणों में संबोधित किया जाएगा।

निष्कर्ष

सभी विकल्प समान आउटपुट देते हैं, लेकिन 2 और 3 प्रभावी हैं, अंत में 3 एक प्रभावी और सुरुचिपूर्ण है (मुझे लगता है)।

डेटाब्रिक्स नोटबुक


24

मुझे पता है कि दिया गया उत्तर और मांगा गया स्कैला के लिए मान लिया गया है, इसलिए मैं सिर्फ पायथन कोड का एक छोटा सा टुकड़ा प्रदान कर रहा हूं यदि एक PySpark उपयोगकर्ता उत्सुक है। वाक्यविन्यास दिए गए उत्तर के समान है, लेकिन सूची को ठीक से पॉप करने के लिए मुझे वास्तव में कॉलम नाम का उल्लेख मैपिंग फ़ंक्शन में दूसरी बार करना है और मुझे चयन कथन की आवश्यकता नहीं है।

यानी एक डेटाफ़्रेम, जिसमें "रॉ" नाम का एक कॉलम होता है

"रॉ" में प्रत्येक पंक्ति मान को एक सूची के रूप में संयोजित करने के लिए जहां प्रत्येक प्रविष्टि "रॉ" से एक पंक्ति मूल्य है जिसका मैं बस उपयोग करता हूं:

MyDataFrame.rdd.map(lambda x: x.Raw).collect()

4
यह रो वस्तुओं की एक सूची देता है। यदि आप मूल्यों की सूची चाहते हैं तो क्या होगा?
ThatDataGuy

यह मानों की एक सूची देता है।
एबी सोभा

इसे साझा करने के लिए धन्यवाद! यह मेरे लिए बहुत अच्छा है कि अगर कोई इस तरह से गति करने का कोई तरीका है, तो यह बहुत धीमी गति से काम करता है
Mojgan Mazouchi

5

स्केल और स्पार्क 2+ में, इसे आज़माएं (मान लें कि आपका कॉलम नाम "s" है): df.select('s).as[String].collect


3
sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets

यह पूरी तरह से काम करता है


1
List<String> whatever_list = df.toJavaRDD().map(new Function<Row, String>() {
    public String call(Row row) {
        return row.getAs("column_name").toString();
    }
}).collect();

logger.info(String.format("list is %s",whatever_list)); //verification

चूँकि java (Real Programming Language) में किसी ने कोई समाधान नहीं दिया है, इसलिए बाद में मुझे धन्यवाद दे सकते हैं


0
from pyspark.sql.functions import col

df.select(col("column_name")).collect()

यहां संग्रह ऐसे कार्य हैं जो बदले में इसे सूची में परिवर्तित करते हैं। विशाल डेटा सेट पर सूची का उपयोग करने के बर्तन बनें। इससे प्रदर्शन में कमी आएगी। डेटा की जांच करना अच्छा है।



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