gpt4 book ai didi

java - pyspark 无法识别 spark.read.load() 中 1989Dec31 和 31Dec1989 等日期的 MMM dateFormat 模式

转载 作者:太空狗 更新时间:2023-10-29 22:25:13 24 4
gpt4 key购买 nike

我遇到了一个非常奇怪的问题 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 一起提供),但也出现错误。

相同的代码在具有相同 Java 版本和 Python 2.7.9 的 Ubuntu Server 15.04 上运行没有任何错误。

official documentation关于spark.read.load()状态:

dateFormat – sets the string that indicates a date format. Custom date formats follow the formats at java.text.SimpleDateFormat. This applies to date type. If None is set, it uses the default value value, yyyy-MM-dd.

official Java documentation谈论MMM作为解析月份名称的正确格式,如 Jan , Dec等,但它会抛出很多以 java.lang.IllegalArgumentException 开头的错误.文档指出 LLL也可以使用,但是pyspark无法识别并抛出 pyspark.sql.utils.IllegalArgumentException: u'Illegal pattern component: LLL' .

我知道 dateFormat 的另一种解决方案,但这是解析数据的最快方式,也是最简单的编码方式。我在这里缺少什么?

为了运行以下示例,您只需放置 test.csvtest.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()

我收到错误。我还尝试在日期和年份之前或之后移动月份名称(例如:1989Dec31yyyyMMMdd)但没有成功。

使用 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|
+----------+

UPDATE1

我制作了一个使用 java.text.SimpleDateFormat 的简单 Java 类:

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,并且我的所有软件都已更新。

有什么想法吗?


UPDATE2

我找到了如何通过指定 Locale.US 使其在纯 Java 下工作:

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 + "\"");
}
}
}

现在,问题变成了:如何在pyspark 中指定Java 的区域设置| ?

最佳答案

可能值得注意的是,这已在 Spark mailing list 上得到解决2016 年 10 月 24 日。根据原始海报:

This worked without setting other options: spark/bin/spark-submit --conf "spark.driver.extraJavaOptions=-Duser.language=en" test.py

并被报告为 SPARK-18076 (将 DateFormat、NumberFormat 中使用的默认区域设置修复为 Locale.US)针对 Spark 2.0.1 并在 Spark 2.1.0 中得到解决。

此外,虽然针对提交者提出的特定问题的上述解决方法(传入 --conf "spark.driver.extraJavaOptions=-Duser.language=en")如果使用,则不再需要Spark 2.1.0,一个显着的副作用是,对于 Spark 2.1.0 用户,您不能再传递类似 --conf "spark.driver.extraJavaOptions=-Duser.language=fr" 如果你想解析一个非英语日期,例如“31mai1989”。

事实上,从 Spark 2.1.0 开始,当使用 spark.read() 加载 csv 时,我认为不再可能使用 dateFormat 选项解析诸如“31mai1989”之类的日期,即使您的默认语言环境是法语。我什至将操作系统中的默认区域和语言更改为法语,并传入了我能想到的几乎所有区域设置排列,即

JAVA_OPTS="-Duser.language=fr -Duser.country=FR -Duser.region=FR" \
JAVA_ARGS="-Duser.language=fr -Duser.country=FR -Duser.region=FR" \
LC_ALL=fr_FR.UTF-8 \
spark-submit \
--conf "spark.driver.extraJavaOptions=-Duser.country=FR -Duser.language=fr -Duser.region=FR" \
--conf "spark.executor.extraJavaOptions=-Duser.country=FR -Duser.language=fr -Duser.region=FR" \
test.py

无济于事,导致

java.lang.IllegalArgumentException
at java.sql.Date.valueOf(Date.java:143)
at org.apache.spark.sql.catalyst.util.DateTimeUtils$.stringToTime(DateTimeUtils.scala:137)

但同样,这只会影响在 Spark 2.1.0 中解析非英语日期。

关于java - pyspark 无法识别 spark.read.load() 中 1989Dec31 和 31Dec1989 等日期的 MMM dateFormat 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40007972/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com