2016-03-17 12 views
6

gün sütun tarih sütununda düşülür nasıl aşağıdaki PySpark DataFrame Pyspark'taki bir tarih sütunundan günler bir sütun nasıl çıkarılır?

df = sqlContext.createDataFrame([('2015-01-15', 10), 
           ('2015-02-15', 5)], 
           ('date_col', 'days_col')) 

Verilen? Bu örnekte, sonuç sütun ['2015-01-05', '2015-02-10'] olmalıdır.

pyspark.sql.functions.date_sub()'a baktım, ancak bir tarih sütunu ve tek bir gün, yani date_sub(df['date_col'], 10) gerektirir. İdeal olarak, date_sub(df['date_col'], df['days_col']) yapmayı tercih ederim.

from datetime import timedelta 
def subtract_date(start_date, days_to_subtract): 
    return start_date - timedelta(days_to_subtract) 

subtract_date_udf = udf(subtract_date, DateType()) 
df.withColumn('subtracted_dates', subtract_date_udf(df['date_col'], df['days_col']) 

Bu teknik olarak çalışır, ancak ben Spark ve Python arasındaki adım büyük veri setleri için performans sorunlarına neden olabilir okudum:

Ben de bir UDF oluşturma çalıştı. Şu an için bu çözüme sadık kalacağım (erken optimizasyona gerek yok), fakat bağırsağım, bu basit şeyi bir Python UDF kullanmadan yapmanın bir yolu olduğunu söyledi.

cevap

3

Bunu, selectExpr kullanarak çözmeyi başarabiliyordum.

df.selectExpr('date_sub(date_col, day_col) as subtracted_dates') 

sadece ifade

df.selectExpr('*', 'date_sub(date_col, day_col) as subtracted_dates') 
+1

Eğer SQL yazmaktan sakıncası yoksa, aslında bunu df.select (expr ("date_sub ({0}, {1})". Format ("date_col", "days_col"))) 'e çevirebilirsiniz. oluşturmak için önemsiz. – zero323

1

hiç değil en zarif çözüm ancak hile yapmak gerekir böyle bir şey sen Scala SQL ifadeleri kesmek istemiyorum (olması gerektiği kadar da zor değil, ancak bu sql özeldir) ise:

from pyspark.sql import Column 

def date_sub_(c1: Column, c2: Column) -> Column: 
    return ((c1.cast("timestamp").cast("long") - 60 * 60 * 24 * c2) 
     .cast("timestamp").cast("date")) 

Python 2.x için yalnızca tür ek açıklamaları bırakın.

+0

Zeki. 'SelectExpr' kullanarak biraz daha zarif bir çözüm buldum, ama yardım için teşekkürler! – kjmij

0

biraz farklı biçim için * ekleyin orijinal DF sütun eklemek istediğiniz değil, aynı zamanda çalışırsa:

df.registerTempTable("dfTbl") 

newdf = spark.sql(""" 
        SELECT *, date_sub(d.date_col, d.day_col) AS DateSub 
        FROM dfTbl d 
        """) 
İlgili konular