2016-02-16 14 views
8

मैं क्लासिक ईटीएल काम करने के लिए PySpark उपयोग कर रहा हूँ (लोड डाटासेट, प्रक्रिया, यह बचाने के लिए) द्वारा विभाजित DataFrame बचाने के लिए और फ़ाइलें/निर्देशिका एक "आभासी" कॉलम के आधार पर विभाजित के रूप में मेरे Dataframe सहेजना चाहते ; क्या मैं "आभासी" मतलब है कि मैं एक स्तंभ समय-चिह्न है जो एक आईएसओ 8601 इनकोडिंग तारीख युक्त एक स्ट्रिंग है, और मुझे वर्ष/माह/दिन से विभाजन करना चाहते हैं है; लेकिन मेरे पास वास्तव में डेटाफ्रेम में वर्ष, महीना या दिन कॉलम नहीं है; मैं इस समय-चिह्न है जहाँ से मैं इन स्तंभों हालांकि प्राप्त कर सकते हैं, लेकिन मैं अपने परिणाम आइटम इन स्तंभों में से एक धारावाहिक के लिए नहीं करना चाहती।स्पार्क: "आभासी" स्तंभ

फ़ाइल संरचना डिस्क पर DataFrame बचत की तरह दिखना चाहिए से उत्पन्न:

/ 
    year=2016/ 
     month=01/ 
      day=01/ 
       part-****.gz 

वहाँ स्पार्क/Pyspark साथ जो मैं चाहता करने के लिए एक तरीका है?

उत्तर

15

कॉलम जो विभाजन के लिए उपयोग किया जाता है धारावाहिक डेटा अपने आप में शामिल नहीं हैं। उदाहरण के लिए आप DataFrame इस तरह बनाते हैं:

df = sc.parallelize([ 
    (1, "foo", 2.0, "2016-02-16"), 
    (2, "bar", 3.0, "2016-02-16") 
]).toDF(["id", "x", "y", "date"]) 

और इसे लिखने के इस प्रकार है:

import tempfile 
from pyspark.sql.functions import col, dayofmonth, month, year 
outdir = tempfile.mktemp() 

dt = col("date").cast("date") 
fname = [(year, "year"), (month, "month"), (dayofmonth, "day")] 
exprs = [col("*")] + [f(dt).alias(name) for f, name in fname] 

(df 
    .select(*exprs) 
    .write 
    .partitionBy(*(name for _, name in fname)) 
    .format("json") 
    .save(outdir)) 

अलग-अलग फ़ाइलों विभाजन कॉलम शामिल नहीं होंगे:

import os 

(sqlContext.read 
    .json(os.path.join(outdir, "year=2016/month=2/day=16/")) 
    .printSchema()) 

## root 
## |-- date: string (nullable = true) 
## |-- id: long (nullable = true) 
## |-- x: string (nullable = true) 
## |-- y: double (nullable = true) 

विभाजन डेटा केवल संग्रहीत किया जाता है निर्देशिका संरचना में और serialized फ़ाइलों में डुप्लिकेट नहीं है। यह केवल तभी संलग्न होगा जब आपका पूरा पूर्ण या आंशिक निर्देशिका पेड़:

sqlContext.read.json(outdir).printSchema() 

## root 
## |-- date: string (nullable = true) 
## |-- id: long (nullable = true) 
## |-- x: string (nullable = true) 
## |-- y: double (nullable = true) 
## |-- year: integer (nullable = true) 
## |-- month: integer (nullable = true) 
## |-- day: integer (nullable = true) 

sqlContext.read.json(os.path.join(outdir, "year=2016/month=2/")).printSchema() 

## root 
## |-- date: string (nullable = true) 
## |-- id: long (nullable = true) 
## |-- x: string (nullable = true) 
## |-- y: double (nullable = true) 
## |-- day: integer (nullable = true) 
+0

मैं अजगर के लिए नया हूं। क्या पथ = वर्ष, और दिन = पथ के बिना ऐसा करने का कोई तरीका है? मैं इनमें से अधिकांश को समझता हूं – deanw