अगर स्पार्क डेटाफ्रेम खाली है तो कैसे जांचें?


101

अभी, मुझे यह df.count > 0जांचने के लिए उपयोग करना है कि DataFrameक्या खाली है या नहीं। लेकिन यह एक तरह से अक्षम है। क्या ऐसा करने का कोई बेहतर तरीका है?

धन्यवाद।

पुनश्च: मैं यह देखना चाहता हूं कि क्या यह खाली है ताकि मैं केवल खाली होने पर ही DataFrameबचाऊं

जवाबों:


154

स्पार्क 2.1.0 के लिए, मेरे सुझाव का उपयोग करना होगा head(n: Int)या उसके take(n: Int)साथ isEmpty, जो भी आपके लिए सबसे स्पष्ट इरादा है।

df.head(1).isEmpty
df.take(1).isEmpty

पायथन समकक्ष के साथ:

len(df.head(1)) == 0  # or bool(df.head(1))
len(df.take(1)) == 0  # or bool(df.take(1))

यदि DataFrame खाली है , तो इसका उपयोग करना df.first()और df.head()दोनों को वापस करना होगा java.util.NoSuchElementException। सीधे first()कॉल head()करता है, जो कॉल करता है head(1).head

def first(): T = head()
def head(): T = head(1).head

head(1)एक एरे को लौटाता है, इसलिए headउस एरे को लेने पर java.util.NoSuchElementExceptionजब डेटाफ़्रेम खाली होता है।

def head(n: Int): Array[T] = withAction("head", limit(n).queryExecution)(collectFromPlan)

इसलिए कॉल करने के बजाय head(), head(1)सरणी प्राप्त करने के लिए सीधे उपयोग करें और फिर आप उपयोग कर सकते हैं isEmpty

take(n)इसके बराबर भी है head(n)...

def take(n: Int): Array[T] = head(n)

और limit(1).collect()के बराबर है head(1)(नोटिस limit(n).queryExecutionमें head(n: Int)कम से कम मैं क्या बता सकता से, विधि) तो निम्नलिखित सब बराबर हैं,, और आप एक को पकड़ने के लिए की जरूरत नहीं होगी java.util.NoSuchElementExceptionअपवाद है जब DataFrame खाली है।

df.head(1).isEmpty
df.take(1).isEmpty
df.limit(1).collect().isEmpty

मुझे पता है कि यह एक पुराना सवाल है, इसलिए उम्मीद है कि यह स्पार्क के नए संस्करण का उपयोग करने में किसी की मदद करेगा।


19
Pyspark का उपयोग करने वालों के लिए। isEmpty कोई बात नहीं है। इसके बजाय len (d.head (1))> 0 करें।
एंटीपॉन79

5
फिर यह बेहतर क्यों है df.rdd.isEmpty?
डैन सिबोरोव्स्की - एमएसएफटी २०'१ows

1
df.head (1) .isEmpty बड़ा समय ले रहा है, इसके लिए कोई अन्य अनुकूलित समाधान है।
राकेश सबबानी

1
अरे @ राकेश सबबानी, अगर आप df.head(1)बड़ी मात्रा में समय ले रहे हैं, तो यह शायद इसलिए है क्योंकि आपकी dfनिष्पादन योजना कुछ जटिल कर रही है जो चिंगारी को शॉर्टकट लेने से रोकती है। उदाहरण के लिए, यदि आप सिर्फ लकड़ी की छत फ़ाइलों से पढ़ रहे हैं df = spark.read.parquet(...), मुझे पूरा यकीन है कि स्पार्क केवल एक फ़ाइल विभाजन को पढ़ेगा। लेकिन अगर आपकी dfअन्य चीजें एकत्रीकरण की तरह कर रही हैं, तो आप अनजाने में स्पार्क को पढ़ने और एक बड़े हिस्से को संसाधित करने के लिए मजबूर हो सकते हैं, यदि सभी नहीं, तो आप स्रोत डेटा।
hulin003

केवल AVOID को मेरे अनुभव की रिपोर्टिंग: मैं df.limit(1).count()भोलेपन का उपयोग कर रहा था । बड़े डेटासेट पर @ hulin003 द्वारा रिपोर्ट किए गए उदाहरणों की तुलना में बहुत अधिक समय लगता है जो लगभग तात्कालिक हैं
Vzzarr

45

मैं सिर्फ अंतर्निहित हड़पने के लिए कहूंगा RDD। स्काला में:

df.rdd.isEmpty

पायथन में:

df.rdd.isEmpty()

यह कहा जा रहा है, यह सब करता है कॉल take(1).length, तो यह रोहन के जवाब के रूप में एक ही बात करेंगे ... बस थोड़ा और अधिक स्पष्ट हो सकता है?


6
यह मेरे मामले में df.count () == 0 की तुलना में आश्चर्यजनक रूप से धीमा है
वास्तुशिल्प

2
एक भारी कार्य में संशोधन नहीं है?
आलोक

1
ज़रुरी नहीं। आरडीडी के अभी भी अधिकांश भाग के लिए स्पार्क की हर चीज का आधार है।
जस्टिन पिहोनी

28
डीएफ को आरडीडी में परिवर्तित न करें। यह प्रक्रिया को धीमा कर देता है। यदि आप इसे रूपांतरित करते हैं तो यह पूरे DF को RDD में बदल देगा और जाँच करेगा कि क्या खाली है। सोचो अगर DF में लाखों पंक्तियाँ हैं, तो RDD को परिवर्तित करने में बहुत समय लगता है।
नंदकिशोर

3
.rdd बहुत प्रक्रिया को धीमा कर देता है जैसे
राउल एच

14

आप यह देखने के लिए head()(या first()) फ़ंक्शन का लाभ उठा सकते हैं कि DataFrameक्या एक एकल पंक्ति है। यदि हां, तो यह खाली नहीं है।


10
यदि डेटाफ्रेम खाली है तो यह "java.util.NoSuchElementException: थ्रू इटरेट्री खाली" पर फेंकता है; [स्पार्क 1.3.1]
फेलिक्सहो

6

यदि आप करते हैं df.count > 0। यह सभी निष्पादकों में सभी विभाजनों की गिनती लेता है और उन्हें चालक में जोड़ देता है। यह तब होता है जब आप लाखों पंक्तियों के साथ काम कर रहे होते हैं।

ऐसा करने का सबसे अच्छा तरीका प्रदर्शन करना है df.take(1)और जांचना है कि क्या इसकी अशक्तता है। यह java.util.NoSuchElementExceptionएक कोशिश चारों ओर लगाने के लिए बेहतर वापस आ जाएगी df.take(1)

take(1)खाली पंक्ति के बजाय डेटाफ़्रेम एक त्रुटि देता है। मैंने विशिष्ट कोड लाइनों को हाइलाइट किया है जहां यह त्रुटि फेंकता है।

यहां छवि विवरण दर्ज करें


1
यदि आप इसे लाखों रिकॉर्ड के साथ बड़े पैमाने पर डेटाफ़्रेम पर चलाते हैं, तो countकुछ समय लगने वाला है।
TheM00s3

2
मैंने वही कहा, मुझे यकीन नहीं है कि आपने एक अंगूठे को क्यों दिया।
नंदकिशोर

आपका अधिकार आपने वही कहा, दुर्भाग्य से, मैंने आपको निराश नहीं किया।
theM00s3

ओह्ह ठीक है। मुझे खेद है TheMoos3, लेकिन जिसने भी यह किया वह कृपया उत्तर का निरीक्षण करें और अवधारणा को समझें।
नंदकिशोर ०६'१६

df.take (1) का उपयोग करते हुए जब df एक खाली ROW प्राप्त करने में खाली परिणाम देता है जिसकी तुलना null के साथ नहीं की जा सकती
LetsPlayYahtzee

6

चूंकि स्पार्क 2.4.0 है Dataset.isEmpty

यह कार्यान्वयन है:

def isEmpty: Boolean = 
  withAction("isEmpty", limit(1).groupBy().count().queryExecution) { plan =>
    plan.executeCollect().head.getLong(0) == 0
}

ध्यान दें कि DataFrameअब स्काला में एक वर्ग नहीं है, यह सिर्फ एक प्रकार का उपनाम है (शायद स्पार्क 2.0 के साथ बदल गया है):

type DataFrame = Dataset[Row]

1
isEmpty df.head (1) की तुलना में धीमा है। TheEmpty
Sandeep540

@ संदीप ५४० वास्तव में? बेंचमार्क? आपका प्रस्ताव कम से कम एक पंक्ति का संकेत देता है। स्पार्क कार्यान्वयन सिर्फ एक संख्या को स्थानांतरित करता है। सिर () सीमा () का उपयोग कर रहा है, साथ ही GroupBy () वास्तव में कुछ भी नहीं कर रहा है, यह एक रिलेशनलग्रुप्डडैटसेट प्राप्त करने के लिए आवश्यक है जो बदले में गिनती () प्रदान करता है। ताकि यह काफी धीमा न हो। यह संभवतः एक डेटा सेट के मामले में तेज होता है जिसमें बहुत सारे कॉलम होते हैं (संभवतः अपसामान्य नेस्टेड डेटा)। आपको कम टाइप करना होगा :-)
बेरिलियम

5

जावा उपयोगकर्ताओं के लिए आप इसे डेटासेट पर उपयोग कर सकते हैं:

public boolean isDatasetEmpty(Dataset<Row> ds) {
        boolean isEmpty;
        try {
            isEmpty = ((Row[]) ds.head(1)).length == 0;
        } catch (Exception e) {
            return true;
        }
        return isEmpty;
}

यह सभी संभावित परिदृश्यों (खाली, अशक्त) की जाँच करता है।


3

Scala में आप विधियों को जोड़ने के लिए isEmpty()और nonEmpty()DataFrame API का उपयोग कर सकते हैं , जो कोड को पढ़ने के लिए थोड़ा अच्छा बना देगा।

object DataFrameExtensions {
  implicit def extendedDataFrame(dataFrame: DataFrame): ExtendedDataFrame = 
    new ExtendedDataFrame(dataFrame: DataFrame)

  class ExtendedDataFrame(dataFrame: DataFrame) {
    def isEmpty(): Boolean = dataFrame.head(1).isEmpty // Any implementation can be used
    def nonEmpty(): Boolean = !isEmpty
  }
}

यहां, अन्य तरीकों को भी जोड़ा जा सकता है। अंतर्निहित रूपांतरण का उपयोग करने के लिए, import DataFrameExtensions._उस फ़ाइल का उपयोग करें जिसे आप विस्तारित कार्यक्षमता का उपयोग करना चाहते हैं। बाद में, तरीकों को सीधे तौर पर इस्तेमाल किया जा सकता है:

val df: DataFrame = ...
if (df.isEmpty) {
  // Do something
}

2

मेरे पास एक ही सवाल था, और मैंने 3 मुख्य समाधान का परीक्षण किया:

  1. df! = null df.count> 0
  2. df.head (1) .isEmpty () @ hulin003 के रूप में सुझाव देते हैं
  3. df.rdd.isEmpty @Justin Pihony के अनुसार

और निश्चित रूप से 3 काम करता है, हालांकि शब्दावलियों की अवधि में, यहां वही है जो मैंने पाया है, जब इन तरीकों को मेरी मशीन में उसी DF पर निष्पादित करते समय, निष्पादन के समय में:

  1. यह ~ 9366ms लेता है
  2. यह ~ 5607ms लेता है
  3. यह ~ 1921ms लेता है

इसलिए मुझे लगता है कि सबसे अच्छा समाधान df.rdd.isEmpty @Justin Pihony सुझाव है


1
विकल्प 3 में कम समय लगता है, दूसरा क्यों?
विचारक

ओह, आपका अधिकार, मैं 3rd का उपयोग कर रहा हूं, मैं प्रतिक्रिया को अपडेट करता
हूं

जिज्ञासा से बाहर ... किस आकार के डेटाफ़्रेम के साथ यह परीक्षण किया गया था?
ऐग्यूफ़र

1

मैंने पाया कि कुछ मामलों पर:

>>>print(type(df))
<class 'pyspark.sql.dataframe.DataFrame'>

>>>df.take(1).isEmpty
'list' object has no attribute 'isEmpty'

यह "लंबाई" के लिए समान है या सिर द्वारा ले () बदलें

[समाधान] इस मुद्दे के लिए हम उपयोग कर सकते हैं।

>>>df.limit(2).count() > 1
False

1

यदि आप Pypsark का उपयोग कर रहे हैं, तो आप भी कर सकते हैं:

len(df.head(1)) > 0

1

PySpark पर, आप भी इसका उपयोग कर सकते bool(df.head(1))एक प्राप्त करने के लिए Trueकी Falseमूल्य

Falseयदि डेटाफ़्रेम में कोई पंक्तियाँ नहीं हैं तो यह वापस आ जाता है


0
df1.take(1).length>0

takeविधि पंक्तियों की सरणी देता है, इसलिए यदि सरणी आकार शून्य के बराबर है, वहाँ में कोई रिकॉर्ड नहीं है df


-1

dataframe.limit(1).count > 0

यह एक नौकरी भी चलाता है लेकिन जब से हम एकल रिकॉर्ड का चयन कर रहे हैं, तब भी अरब पैमाने के रिकॉर्ड के मामले में समय की खपत बहुत कम हो सकती है।

प्रेषक: https://medium.com/checking-emptiness-in-distributed-objects/count-vs-isempty-surprised-to-see-the-impact-fa70c0246ee0


ये सभी बुरे विकल्प हैं जो लगभग बराबर समय लेते हैं
पुष्पेंद्र जायसवाल

@PushpendraJaiswal हाँ, और बुरे विकल्पों की दुनिया में, हमें सबसे अच्छे बुरे विकल्प को चुनना चाहिए
जॉर्डन मॉरिस

-2

आप इसे कर सकते हैं जैसे:

val df = sqlContext.emptyDataFrame
if( df.eq(sqlContext.emptyDataFrame) )
    println("empty df ")
else 
    println("normal df")

1
कभी वापस लौटने के लिए schemaदो डेटाफ्रेम ( sqlContext.emptyDataFrame& df) के समान होने की आवश्यकता नहीं होगी true?
y2k-shubham

1
यह काम नहीं करेगा। eqसे विरासत में मिला है AnyRefऔर परीक्षण करता है कि क्या तर्क (वह) रिसीवर ऑब्जेक्ट (यह) का संदर्भ है।
एलपर टी। तुर्क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.