我有以下示例数据框,其中包含对象ID和总时数。十进制值将分钟转换为一小时的一部分。
# +----+----+--------+
# |col1|total_hours |
# +----+-------------+
# |obj1| 48387.837 |
# |obj2| 45570.0201 |
# |obj3| 39339.669 |
# |obj4| 37673.235 |
# |obj5| 3576 |
# |obj6| 15287.9999 |
# +----+-------------+
我想以小时:分钟格式显示总时数。
所需的输出:
# +----+----+--------+
# |col1|total_hours |
# +----+-------------+
# |obj1| 48387:50 |
# |obj2| 45570:01 |
# |obj3| 39339:40 |
# |obj4| 37673:14 |
# |obj5| 3576:00 |
# |obj6| 15288:00 |
# +----+-------------+
在SQL中,我可以使用以下功能:
hr = trunc(col1);
minutes = round(hr -trunc(hr)* 0.6, 2);
hours_minutes= trim(replace(to_char(hr + minutes ,'999999999990.90'),'.',':'));
如何在Pyspark中完成
?答案 0 :(得分:3)
鉴于简单的格式无法使用,因此这将需要字符串操作。 这是获取数字的模数,将其乘以60,同时格式化两者,然后进行级联:
df.withColumn('total_hours_str',
f.concat(f.regexp_replace(f.format_number(f.floor(df.total_hours), 0), ',', ''),
f.lit(':'),
f.lpad(f.format_number(df.total_hours%1*60, 0), 2, '0'))).show()
输出:
+----+-----------+---------------+
|col1|total_hours|total_hours_str|
+----+-----------+---------------+
|obj1| 48387.837| 48387:50|
|obj2| 45570.0201| 45570:01|
|obj3| 39339.669| 39339:40|
|obj4| 37673.235| 37673:14|
|obj5| 3576.0| 3576:00|
+----+-----------+---------------+
编辑:
由于小数部分的值最终会四舍五入为整整一个小时,因此建议您在处理该列之前先四舍五入:
df.withColumn('rounded_total_hours', f.round(df['total_hours'],2))\
.withColumn('total_hours_str',
f.concat(f.regexp_replace(f.format_number(f.floor(f.col('rounded_total_hours')), 0), ',', ''),
f.lit(':'),
f.lpad(f.format_number(f.col('rounded_total_hours')%1*60, 0), 2, '0'))).show()
哪个会产生:
+----+-----------+-------------------+---------------+
|col1|total_hours|rounded_total_hours|total_hours_str|
+----+-----------+-------------------+---------------+
|obj1| 48387.837| 48387.84| 48387:50|
|obj2| 45570.0201| 45570.02| 45570:01|
|obj3| 39339.669| 39339.67| 39339:40|
|obj4| 37673.235| 37673.24| 37673:14|
|obj5| 3576.0| 3576.0| 3576:00|
|obj6| 15287.9999| 15288.0| 15288:00|
+----+-----------+-------------------+---------------+
答案 1 :(得分:0)
如果所需的数据类型是字符串,则可以使用字符串concat完成。
步骤:
total_hours
强制转换为
IntegerType()
total_hours
中减去该值来提取小时数。:
分隔符广播到字符串和concat。代码:
from pyspark.sql.types import IntegerType
from pyspark.sql.functions import concat_ws
df = df.withColumn('total_hour_int', df['total_hours'].cast(IntegerType())
df = df.withColumn('hours_remainder', df['total_hours']-df['total_hour_int'])
df = df.withColumn('minutes', df['hours_remainder']*60)
df = df.withColumn('minutes_full', df['minutes'].cast(IntegerType())
df = df.withColumn('total_hours_string', concat_ws(':', df['total_hour_int'], df['minutes_full'])