我想将数据框中的月份数列更改为月份名称(pyspark)

时间:2017-06-05 20:21:51

标签: pyspark pyspark-sql

我在数据框中有一列月份编号,并希望将其更改为月份名称,因此我使用了这个:

df['monthName'] = df['monthNumber'].apply(lambda x: calendar.month_name[x]) 

但它引发了以下错误:

TypeError:'列'对象不可调用

请告诉我解决此问题的方法有哪些。我是python和spark的新手

Edit1:我使用Spark 2.1.1和Python 2.7.6

这是我的航空公司数据分析代码。

df_withDelay = df_mappedCarrierNames.filter(df_mappedCarrierNames.ArrDelay > 0)
sqlContext.registerDataFrameAsTable(df_withDelay,"SFO_ArrDelayAnalysisTable")
df_SFOArrDelay = sqlContext.sql \
                      ("select sfo.Month, sum(sfo.ArrDelay) as TotalArrivalDelay \
                      from SFO_ArrDelayAnalysisTable sfo \
                      where (sfo.Dest = 'SFO') \
                      group by sfo.Month")

我正在尝试使用Month vs ArrDelay绘制图表。从上面的代码我得到月数作为数字。所以我尝试使用以下选项

udf = UserDefinedFunction(lambda x: calendar.month_abbr[int(x)], StringType())
new_df_mappedCarrierNames = df_mappedCarrierNames.select(*[udf(column).alias(name) if column == name else column for column in df_mappedCarrierNames.columns])

它有效,但在我的图表中,它没有按排序顺序排列。而如果我使用月份数字,则按排序顺序排列。我的问题是找出如何从Jan到dec按照排序顺序将月份数字映射到月份名称。 提前感谢您的回复。

3 个答案:

答案 0 :(得分:2)

这是干净的解决方案:

from pyspark.sql.functions import UserDefinedFunction
from pyspark.sql.types import StringType

#1
month_lst = ['January', 'Feburary', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
#2
df = sqlContext.createDataFrame( [(1, "a", 23.0), (3, "B", -23.0)], ("x1", "x2", "x3"))

name = 'x1'
#3
udf = UserDefinedFunction(lambda x: month_lst[int(x%12) - 1], StringType())
new_df = df.select(*[udf(column).alias(name) if column == name else column for column in df.columns])

1

您构建字典

2

定义数据框并选择列 3 month_lst[int(x%12) - 1]这是重要的部分,我只假设输入是一个浮点数,并从列表中返回一个值

如果您需要更多帮助,请添加评论,

答案 1 :(得分:0)

如果可能的话,我会避免使用UDF(因为它们的伸缩性不好)。尝试结合使用to_date(),date_format()和转换为整数:

from pyspark.sql.functions import col

df = df.withColumn('monthNumber', date_format(to_date(col('monthName'), 'MMMMM'), 'MM').cast('int'))

日期格式代码的详细信息: http://tutorials.jenkov.com/java-internationalization/simpledateformat.html

答案 2 :(得分:0)

您可以执行以下步骤: 输入 2012年5月20日

过程

df_train = df_train.withColumn("dates", from_unixtime(unix_timestamp(df_train.dates, 'MMMMM dd  yyy')))

输出:2012-05-20 00:00:00

month_udf = udf(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S').strftime("%B"), returnType = StringType())
dftest = df_train.withColumn("monthname", month_udf(df_train.dates))

输出:5月