У меня возникла очень странная проблема с pyspark
в macOS Sierra. Моя цель - анализировать даты в формате ddMMMyyyy
(например: 31Dec1989
), но получать ошибки. Я использую Spark 2.0.1, Python 2.7.10 и Java 1.8.0_101. Я также пытался использовать Anaconda 4.2.0 (она поставляется с Python 2.7.12), но тоже получаю ошибки.
Тот же код на Ubuntu Server 15.04 с той же версией Java и Python 2.7.9 работает без ошибок.
В официальной документации о spark.read.load()
говорится:
dateFormat
— задает строку, указывающую формат даты. Пользовательские форматы даты следуют форматам вjava.text.SimpleDateFormat
. Это относится к типу даты. Если установлено None, используется значение по умолчанию,yyyy-MM-dd
.
В официальной документации по Java говорится о MMM
как о правильный формат для анализа названий месяцев, таких как Jan
, Dec
и т. д., но он выдает много ошибок, начинающихся с java.lang.IllegalArgumentException
. В документации указано, что LLL
тоже можно использовать, но pyspark
не распознает его и выдает pyspark.sql.utils.IllegalArgumentException: u'Illegal pattern component: LLL'
.
Я знаю другое решение для dateFormat
, но это самый быстрый способ анализа данных и самый простой код. Что мне здесь не хватает?
Чтобы запустить следующие примеры, вам просто нужно поместить test.csv
и test.py
в один и тот же каталог, а затем запустить <spark-bin-directory>/spark-submit <working-directory>/test.py
.
Мой тестовый пример с использованием формата ddMMMyyyy
У меня есть текстовый файл с именем test.csv
, содержащий следующие две строки:
col1
31Dec1989
и код следующий:
from pyspark.sql import SparkSession
from pyspark.sql.types import *
spark = SparkSession \
.builder \
.appName("My app") \
.config("spark.some.config.option", "some-value") \
.getOrCreate()
struct = StructType([StructField("column", DateType())])
df = spark.read.load( "test.csv", \
schema=struct, \
format="csv", \
sep=",", \
header="true", \
dateFormat="ddMMMyyyy", \
mode="FAILFAST")
df.show()
Я получаю ошибки. Я также безуспешно пытался переместить название месяца до или после дня и года (например: 1989Dec31
и yyyyMMMdd
).
Рабочий пример с использованием формата ddMMyyyy
Этот пример идентичен предыдущему, за исключением формата даты. test.csv
теперь содержит:
col1
31121989
Следующий код выводит содержимое test.csv
:
from pyspark.sql import SparkSession
from pyspark.sql.types import *
spark = SparkSession \
.builder \
.appName("My app") \
.config("spark.some.config.option", "some-value") \
.getOrCreate()
struct = StructType([StructField("column", DateType())])
df = spark.read.load( "test.csv", \
schema=struct, \
format="csv", \
sep=",", \
header="true", \
dateFormat="ddMMyyyy", \
mode="FAILFAST")
df.show()
Вывод следующий (я опускаю различные подробные строки):
+----------+
| column|
+----------+
|1989-12-31|
+----------+
ОБНОВЛЕНИЕ1
Я сделал простой класс Java, который использует java.text.SimpleDateFormat
:
import java.text.*;
import java.util.Date;
class testSimpleDateFormat
{
public static void main(String[] args)
{
SimpleDateFormat format = new SimpleDateFormat("yyyyMMMdd");
String dateString = "1989Dec31";
try {
Date parsed = format.parse(dateString);
System.out.println(parsed.toString());
}
catch(ParseException pe) {
System.out.println("ERROR: Cannot parse \"" + dateString + "\"");
}
}
}
Этот код не работает в моей среде и выдает эту ошибку:
java.text.ParseException: Unparseable date: "1989Dec31"
но отлично работает в другой системе (Ubuntu 15.04). Это похоже на проблему с Java, но я не знаю, как ее решить. Я установил последнюю доступную версию Java, и все мое программное обеспечение было обновлено.
Любые идеи?
ОБНОВЛЕНИЕ 2
Я нашел, как заставить его работать на чистой Java, указав Locale.US
:
import java.text.*;
import java.util.Date;
import java.util.*;
class HelloWorldApp
{
public static void main(String[] args)
{
SimpleDateFormat format = new SimpleDateFormat("yyyyMMMdd", Locale.US);
String dateString = "1989Dec31";
try {
Date parsed = format.parse(dateString);
System.out.println(parsed.toString());
}
catch(ParseException pe) {
System.out.println(pe);
System.out.println("ERROR: Cannot parse \"" + dateString + "\"");
}
}
}
Теперь возникает вопрос: как указать локаль Java в pyspark
?