2016-04-14 4 views
5

रखते हुए डेटाफ्रेम पर ड्रॉप ड्रॉप डुप्लिकेट कैसे करें मेरे पास एक ऐसा केस है जहां मुझे डेटाफ्रेम की डुप्लिकेट पंक्तियां छोड़नी होंगी (इस मामले में डुप्लिकेट का अर्थ है कि उनके पास एक ही 'आईडी' फ़ील्ड है) पंक्ति को उच्चतम 'टाइमस्टैंप' (यूनिक्स टाइमस्टैम्प) फ़ील्ड के साथ रखते हुए।स्पार्क: उच्चतम टाइमस्टैम्प वाली पंक्ति

मुझे drop_duplicate विधि मिली (मैं pyspark का उपयोग कर रहा हूं), लेकिन किसी पर नियंत्रण नहीं है कि किस आइटम को रखा जाएगा।

कोई भी मदद कर सकता है? अग्रिम में Thx

उत्तर

6

एक मैनुअल मानचित्र और कम कार्यक्षमता जो आप चाहते हैं कार्यक्षमता प्रदान करने के लिए आवश्यक हो सकता है।

def selectRowByTimeStamp(x,y): 
    if x.timestamp > y.timestamp: 
     return x 
    return y 

dataMap = data.map(lambda x: (x.id, x)) 
uniqueData = dataMap.reduceByKey(selectRowByTimeStamp) 

यहां हम आईडी के आधार पर सभी डेटा को समूहीकृत कर रहे हैं। फिर, जब हम समूह को कम कर रहे हैं, तो हम रिकॉर्ड को उच्चतम टाइमस्टैम्प के साथ रखते हुए ऐसा करते हैं। जब कोड कम हो जाता है, तो प्रत्येक आईडी के लिए केवल 1 रिकॉर्ड छोड़ा जाएगा।

+0

क्या है 'डेटामैप 'का उद्देश्य? – zero323

+1

वास्तव में यह 'data.map होना चाहिए (लैम्ब्डा x: (x.id, x))' (या 'keyBy')। आइए इसे ठीक करें। – zero323

+0

बिल्कुल सही, अच्छा पकड़ – David

2

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

val df = Seq(
    (1,12345678,"this is a test"), 
    (1,23456789, "another test"), 
    (2,2345678,"2nd test"), 
    (2,1234567, "2nd another test") 
).toDF("id","timestamp","data") 

+---+---------+----------------+ 
| id|timestamp|   data| 
+---+---------+----------------+ 
| 1| 12345678| this is a test| 
| 1| 23456789| another test| 
| 2| 2345678|  2nd test| 
| 2| 1234567|2nd another test| 
+---+---------+----------------+ 

df.join(
    df.groupBy($"id").agg(max($"timestamp") as "r_timestamp").withColumnRenamed("id", "r_id"), 
    $"id" === $"r_id" && $"timestamp" === $"r_timestamp" 
).drop("r_id").drop("r_timestamp").show 
+---+---------+------------+ 
| id|timestamp|  data| 
+---+---------+------------+ 
| 1| 23456789|another test| 
| 2| 2345678| 2nd test| 
+---+---------+------------+ 

तुम वहाँ एक id के लिए एक दोहराया timestamp हो सकता है (नीचे टिप्पणी देखें) उम्मीद हैं, तो आप ऐसा कर सकते हैं:

df.dropDuplicates(Seq("id", "timestamp")).join(
    df.groupBy($"id").agg(max($"timestamp") as "r_timestamp").withColumnRenamed("id", "r_id"), 
    $"id" === $"r_id" && $"timestamp" === $"r_timestamp" 
).drop("r_id").drop("r_timestamp").show 
+1

यह करीब है लेकिन प्रति आईडी एक पंक्ति की गारंटी नहीं देता है। – zero323

+0

हम्म, आपका मतलब है कि टाइमस्टैम्प वही है? –

+0

हां, बिल्कुल। मुझे लगता है कि यहां एक मनमाना लेना संभव होना चाहिए। – zero323

संबंधित मुद्दे