【问题标题】:How to modify/transform the column of a dataframe?如何修改/转换数据框的列?
【发布时间】:2016-12-27 06:37:53
【问题描述】:

我有一个使用

创建的 pyspark.sql.dataframe.DataFrame 实例
dataframe = sqlContext.sql("select * from table").

一列是“arrival_date”并包含一个字符串。

如何修改此列,以便仅从中取出前 4 个字符并丢弃其余字符?

如何将此列的类型从字符串转换为日期?

在 graphlab.SFrame 中,这将是:

dataframe['column_name'] = dataframe['column_name'].apply(lambda x: x[:4] )

dataframe['column_name'] = dataframe['column_name'].str_to_datetime()

【问题讨论】:

  • @Orions 我只是还没来得及测试提出的解决方案。感谢您的帮助。
  • 我想给自己足够的时间来测试每个答案,并在接受之前找到一个可行的答案。谢谢你的提醒。我现在就这样做。再次感谢您的帮助。

标签: python apache-spark pyspark apache-spark-sql


【解决方案1】:

正如 Orions 所说,您不能修改列,但可以覆盖它。此外,您不需要创建用户定义的函数,因为有一个用于提取子字符串的内置函数:

from pyspark.sql.functions import *
df = df.withColumn("arrival_date", df['arrival_date'].substr(0, 4))

要将其转换为日期,您可以使用 to_date,正如 Orions 所说:

from pyspark.sql.functions import *
df = df.withColumn("arrival_date", to_date(df['arrival_date'].substr(0, 4)))

但是,如果需要指定格式,则应使用unix_timestamp:

from pyspark.sql.functions import *
format = 'yyMM'
col = unix_timestamp(df['arrival_date'].substr(0, 4), format).cast('timestamp')
df = df.withColumn("arrival_date", col)

这一切都可以在pyspark documentation找到。

【讨论】:

  • 谢谢!我试过了,没有错误,但新列中的所有值都变成了“空”而不是有意义的数字。您认为问题出在我选择“mm/dd/yyyy”的格式上吗? (日期格式为 2016 年 5 月 16 日)
  • @Semihcan 您需要根据字符串中的内容调整格式。原始列中的值如何?
  • 2016 年 5 月 16 日就像 5/16/2016,看起来像 m/dd/yyyy,但 2016 年 12 月 15 日是 12/16/2016,就像 mm/dd/yyyy 所以这很棘手让我知道是输入 mm/dd/yyyy 还是 m/dd/yyyy 等
  • @Semihcan,是的 df=old_df。对不起
  • @Semihcan,好的。你的版本有问题。强制转换前必须将 Unix_timestamp() 的结果乘以 1000
【解决方案2】:

要从 arrival_date (StringType) 列中提取前 4 个字符,请使用 UserDefinedFunction 创建一个 new_df(因为您无法修改这些列:它们是不可变的):

from pyspark.sql.functions import UserDefinedFunction, to_date

old_df = spark.sql("SELECT * FROM table")
udf = UserDefinedFunction(lambda x: str(x)[:4], StringType())
new_df = old_df.select(*[udf(column).alias('arrival_date') if column == 'arrival_date' else column for column in old_df.columns])

要将arrival_date (StringType) 列转换为DateType 列,请使用to_date 函数,如下所示:

new_df = old_df.select(old_df.other_cols_if_any, to_date(old_df.arrival_date).alias('arrival_date'))

来源:
https://stackoverflow.com/a/29257220/2873538
https://databricks.com/blog/2015/09/16/apache-spark-1-5-dataframe-api-highlights.html

【讨论】:

  • 请参阅Daniel de Paula's answer 以更有效地完成新的子字符串列。为此声明和使用 UDF 效率极低,您可以轻松地将列添加到现有数据框,而无需构建全新的数据框。
猜你喜欢
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 2018-02-08
  • 1970-01-01
  • 2021-08-09
相关资源
最近更新 更多