Читайте в CSV в Pyspark с правильными типами данных - PullRequest
0 голосов
/ 26 октября 2018

Когда я пытаюсь импортировать локальный CSV с помощью spark, каждый столбец по умолчанию читается как строка.Однако мои столбцы содержат только целые числа и тип отметки времени.Чтобы быть более конкретным, CSV выглядит следующим образом:

"Customer","TransDate","Quantity","PurchAmount","Cost","TransID","TransKey"
149332,"15.11.2005",1,199.95,107,127998739,100000

Я нашел код, который должен работать в этот вопрос , но при его выполнении все записи возвращаются как NULL.

Я использую следующее для создания пользовательской схемы:

from pyspark.sql.types import LongType, StringType, StructField, StructType, BooleanType, ArrayType, IntegerType, TimestampType

customSchema = StructType(Array(
        StructField("Customer", IntegerType, true),
        StructField("TransDate", TimestampType, true),
        StructField("Quantity", IntegerType, true),
        StructField("Cost", IntegerType, true),
        StructField("TransKey", IntegerType, true)))

и затем читаю в CSV с:

myData = spark.read.load('myData.csv', format="csv", header="true", sep=',', schema=customSchema)

Что возвращает:

+--------+---------+--------+----+--------+
|Customer|TransDate|Quantity|Cost|Transkey|
+--------+---------+--------+----+--------+
|    null|     null|    null|null|    null|
+--------+---------+--------+----+--------+

Я пропустил важный шаг?Я подозреваю, что столбец Дата является корнем проблемы.Примечание. Я запускаю это в GoogleCollab.

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Вот, пожалуйста!

"Customer","TransDate","Quantity","PurchAmount","Cost","TransID","TransKey"
149332,"15.11.2005",1,199.95,107,127998739,100000
PATH_TO_FILE="file:///u/vikrant/LocalTestDateFile"
Loading above file to dataframe:
df = spark.read.format("com.databricks.spark.csv") \
  .option("mode", "DROPMALFORMED") \
  .option("header", "true") \
  .option("inferschema", "true") \
  .option("delimiter", ",").load(PATH_TO_FILE)

ваша дата будет загружена в виде строкового столбца, но как только вы измените ее на тип даты, он будет обрабатывать этот формат даты как NULL.

df = (df.withColumn('TransDate',col('TransDate').cast('date'))

+--------+---------+--------+-----------+----+---------+--------+
|Customer|TransDate|Quantity|PurchAmount|Cost|  TransID|TransKey|
+--------+---------+--------+-----------+----+---------+--------+
|  149332|     null|       1|     199.95| 107|127998739|  100000|
+--------+---------+--------+-----------+----+---------+--------+

Так что нам нужно изменить формат даты с дд.мм.гг на гг-мм-дд.

from datetime import datetime
from pyspark.sql.functions import col, udf
from pyspark.sql.types import DateType
from pyspark.sql.functions import col

Функция Python для изменения формата даты:

  change_dateformat_func =  udf (lambda x: datetime.strptime(x, '%d.%m.%Y').strftime('%Y-%m-%d'))

сейчас вызовите эту функцию для вашего столбца данных:

newdf = df.withColumn('TransDate', change_dateformat_func(col('TransDate')).cast(DateType()))

+--------+----------+--------+-----------+----+---------+--------+
|Customer| TransDate|Quantity|PurchAmount|Cost|  TransID|TransKey|
+--------+----------+--------+-----------+----+---------+--------+
|  149332|2005-11-15|       1|     199.95| 107|127998739|  100000|
+--------+----------+--------+-----------+----+---------+--------+

и ниже - схема:

 |-- Customer: integer (nullable = true)
 |-- TransDate: date (nullable = true)
 |-- Quantity: integer (nullable = true)
 |-- PurchAmount: double (nullable = true)
 |-- Cost: integer (nullable = true)
 |-- TransID: integer (nullable = true)
 |-- TransKey: integer (nullable = true)

Дайте мне знать, работает ли она для вас.

0 голосов
/ 27 октября 2018

Попытка использовать RDD, а затем переформатировать дату, используя лямбду с правильным форматом YYYY-MM-DD, а затем преобразовать ее в формат данных.Позвольте мне, если это работает, или вам нужен код для этого.

...