Scala 如何使用Spark在CSV文件中创建新的顺序时间戳列

Scala 如何使用Spark在CSV文件中创建新的顺序时间戳列,scala,apache-spark,pyspark,apache-spark-sql,Scala,Apache Spark,Pyspark,Apache Spark Sql,我有一个示例CSV文件,其中的列如下所示 col1,col2 1,57.5 2,24.0 3,56.7 4,12.5 5,75.5 col1,col2,ts 1,57.5,00:00:00 2,24.0,00:00:01 3,56.7,00:00:02 4,12.5,00:00:03 5,75.5,00:00:04 我希望在HH:mm:ss格式中有一个新的Timestamp列,并且时间戳应以秒为单位持续增加,如下所示 col1,col2 1,57.5 2,24.0 3,56.7 4,12.5

我有一个示例CSV文件,其中的列如下所示

col1,col2
1,57.5
2,24.0
3,56.7
4,12.5
5,75.5
col1,col2,ts
1,57.5,00:00:00
2,24.0,00:00:01
3,56.7,00:00:02
4,12.5,00:00:03
5,75.5,00:00:04
我希望在
HH:mm:ss
格式中有一个新的
Timestamp
列,并且时间戳应以秒为单位持续增加,如下所示

col1,col2
1,57.5
2,24.0
3,56.7
4,12.5
5,75.5
col1,col2,ts
1,57.5,00:00:00
2,24.0,00:00:01
3,56.7,00:00:02
4,12.5,00:00:03
5,75.5,00:00:04

提前感谢您的帮助。

我可以提出一个基于
pyspark
的解决方案。scala的
scala
实现应该几乎是透明的

我的想法是创建一个包含唯一时间戳的列(这里以1980年为例,但并不重要),并根据第一列(行号)添加秒数。然后,您只需重新格式化时间戳,使其仅显示小时数

import pyspark.sql.函数作为psf
df=(df
.withColumn(“ts”,psf.unix_时间戳(timestamp=psf.lit('1980-01-01 00:00:00'),format='YYYY-MM-dd HH:MM:ss'))
.带列(“ts”,psf列(“ts”)+psf列(“i”)-1)
.withColumn(“ts”,psf.from_unixtime(“ts”,format='HH:mm:ss'))
)
df.show(2)
+---+----+---------+
|i|x|ts|
+---+----+---------+
|  1|57.5| 00:00:00|
|  2|24.0| 00:00:01|
+---+----+---------+
仅显示前2行
数据生成
df=spark.createDataFrame([(1,57.5),
(2,24.0),
(3,56.7),
(4,12.5),
(5,75.5)],[i',x']
df.show(2)
+---+----+
|i | x|
+---+----+
|  1|57.5|
|  2|24.0|
+---+----+
仅显示前2行
更新:如果您的csv中没有行号(来自您的评论) 在这种情况下,您将需要
行号
功能

在Spark中对行进行编号并不简单,因为数据分布在独立的分区和位置上。将文件行映射到分区时,
spark
将不遵守csv中观察到的顺序。我认为如果文件中的顺序很重要,最好不要使用
Spark
对csv中的行进行编号。基于
pandas
的预处理步骤,在所有文件上循环,一次处理一个文件,可以使其工作

无论如何,如果您不介意将行顺序与存储在磁盘中的csv中的行顺序不同,我可以向您提出一个解决方案

将pyspark.sql.window导入为psw
w=psw.Window.partitionBy().orderBy(“x”)
(df)
.删除(“i”)
.带列(“i”,psf.行号(),在(w)上方)
.withColumn(“Timestamp”,psf.unix_Timestamp(Timestamp=psf.lit('1980-01-01 00:00:00')),format='YYYY-MM-dd HH:MM:ss'))
.带列(“时间戳”,psf.col(“时间戳”)+psf.col(“i”)-1)
.withColumn(“Timestamp”,psf.from_unixtime(“Timestamp”,format='HH:mm:ss'))
.表演(2)
)
+----+---+---------+
|x | i |时间戳|
+----+---+---------+
|12.5|  1| 00:00:00|
|24.0|  2| 00:00:01|
+----+---+---------+
仅显示前2行
就效率而言,这很糟糕(就像在master中收集所有数据),因为您没有使用
partitionBy
。在这一步中,使用
Spark
是过度杀戮

您还可以使用临时列并使用此列进行排序。在这个特定的例子中,它将产生预期的输出,但不确定它是否在一般情况下工作良好

w2=psw.Window.partitionBy().orderBy(“临时”)
(df)
.删除(“i”)
带柱(“温度”,psf照明(1))
.withColumn(“i”,psf.行号()。在(w2)上方)
.withColumn(“Timestamp”,psf.unix_Timestamp(Timestamp=psf.lit('1980-01-01 00:00:00')),format='YYYY-MM-dd HH:MM:ss'))
.带列(“时间戳”,psf.col(“时间戳”)+psf.col(“i”)-1)
.withColumn(“Timestamp”,psf.from_unixtime(“Timestamp”,format='HH:mm:ss'))
.表演(2)
)
+----+----+---+---------+
|x | temp | i |时间戳|
+----+----+---+---------+
|57.5|   1|  1| 00:00:00|
|24.0|   1|  2| 00:00:01|
+----+----+---+---------+
仅显示前2行

Hi Linog,如果我没有“I”(即col1)列怎么办。这是示例数据集。我在原始数据集中没有“I”列您是否有一个列来对数据进行分区或排序?我想它需要一个窗口函数。在
spark
中,行编号的概念并不自然,因为在同一分区中没有所有行。有可能找到一个黑客,但这可能是低效的,尤其是对于大型数据集SNO。我没有任何要分区的列。我有100个文件来操作这个TS列并将它们合并成一个。我更新了答案。要创建行号,spark可能不是最好的工具。你的步子对我很管用。我刚刚将您的步骤转换为scala。