2015-12-18 6 views
6

私の質問は、列を複数の列に分割する方法です。 なぜdf.toPandas()が機能しないのか分かりません。pysparkは、パンダなしで列を複数の列に分割します。

たとえば、 'df_test'を 'df_test2'に変更したいとします。 pandasモジュールを使用した例がたくさんありました。別の方法がありますか? ありがとうございます。

df_test = sqlContext.createDataFrame([ 
(1, '14-Jul-15'), 
(2, '14-Jun-15'), 
(3, '11-Oct-15'), 
], ('id', 'date')) 

df_test2

id  day month year 
1  14  Jul  15 
2  14  Jun  15 
1  11  Oct  15 

答えて

10

スパーク> = 2.2

あなたはunix_timestampとキャストをスキップしてto_dateまたはto_timestampを使用することができます。

from pyspark.sql.functions import to_date, to_timestamp 

df_test.withColumn("date", to_date("date", "dd-MMM-yy")).show() 
## +---+----------+ 
## | id|  date| 
## +---+----------+ 
## | 1|2015-07-14| 
## | 2|2015-06-14| 
## | 3|2015-10-11| 
## +---+----------+ 


df_test.withColumn("date", to_timestamp("date", "dd-MMM-yy")).show() 
## +---+-------------------+ 
## | id|    date| 
## +---+-------------------+ 
## | 1|2015-07-14 00:00:00| 
## | 2|2015-06-14 00:00:00| 
## | 3|2015-10-11 00:00:00| 
## +---+-------------------+ 

し、他のdatetを適用しますime関数を以下に示します。

スパーク< 2.2

単一のアクセスに複数のトップレベル列を導出することはできません。

from pyspark.sql.types import StringType, StructType, StructField 
from pyspark.sql import Row 
from pyspark.sql.functions import udf, col 

schema = StructType([ 
    StructField("day", StringType(), True), 
    StructField("month", StringType(), True), 
    StructField("year", StringType(), True) 
]) 

def split_date_(s): 
    try: 
     d, m, y = s.split("-") 
     return d, m, y 
    except: 
     return None 

split_date = udf(split_date_, schema) 

transformed = df_test.withColumn("date", split_date(col("date"))) 
transformed.printSchema() 

## root 
## |-- id: long (nullable = true) 
## |-- date: struct (nullable = true) 
## | |-- day: string (nullable = true) 
## | |-- month: string (nullable = true) 
## | |-- year: string (nullable = true) 

が、それだけではなく、かなりPySparkで冗長でなく、高価である:あなたはこのようなUDFで構造体やコレクション型を使用することができます。日付ベースの変換のために

あなたは単に組み込み関数を使用することができます。

from pyspark.sql.functions import unix_timestamp, dayofmonth, year, date_format 

transformed = (df_test 
    .withColumn("ts", 
     unix_timestamp(col("date"), "dd-MMM-yy").cast("timestamp")) 
    .withColumn("day", dayofmonth(col("ts")).cast("string")) 
    .withColumn("month", date_format(col("ts"), "MMM")) 
    .withColumn("year", year(col("ts")).cast("string")) 
    .drop("ts")) 

同様に、あなたは、日付文字列を分割するregexp_extractを使用することができます。

Derive multiple columns from a single column in a Spark DataFrame

参照してください:あなたはSPARK-11724に対してパッチを当てていないバージョンを使用している場合

これはunix_timestamp(...)後とcast("timestamp")前に修正が必要になります。

+0

spark 2.xのこの回答が更新されているのだろうか。ありがとう! – Kai

+1

@Kai Spark 2.2では 'unix_timestamp'をスキップできますが、これが唯一の重要な変更です。残りはほぼ同じですが、SQL関数が推奨されています。 – zero323

+0

速い返信をいただきありがとうございます。 – Kai

関連する問題