我有一个DataFrame
,其列为“ id”和“ date”。日期的格式为yyyy-mm-dd,下面是一个示例:
+---------+----------+
| item_id| ds|
+---------+----------+
| 25867869|2018-05-01|
| 17190474|2018-01-02|
| 19870756|2018-01-02|
|172248680|2018-07-29|
| 41148162|2018-03-01|
+---------+----------+
我想创建一个新列,其中每个日期都与一个从1开始的整数相关联,这样最小(最早)的日期将得到整数1,下一个(最早的第二个日期)将被分配给2,依此类推。
我希望我的DataFrame
看起来像这样...:
+---------+----------+---------+
| item_id| ds| number|
+---------+----------+---------+
| 25867869|2018-05-01| 3|
| 17190474|2018-01-02| 1|
| 19870756|2018-01-02| 1|
|172248680|2018-07-29| 4|
| 41148162|2018-03-01| 2|
+---------+----------+---------+
说明:
最早的日期是1月02日,因此它的编号是1。由于有2行具有相同的日期,因此1被定位两次。在2018年1月2日之后,下一个日期为2018年3月1日,因此其编号为2,依此类推...我如何创建此类列?
答案 0 :(得分:1)
这可以通过dense_rank
函数中的Window
来实现。
import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions._
val win = Window.orderBy(to_date(col("ds"),"yyyy-MM-dd").asc)
val df1 = df.withColumn("number", dense_rank() over win)
df1
将根据需要包含列number
。
请注意:to_date(col("ds"),"yyyy-MM-dd")
是强制性的,否则将被视为字符串,并且无法达到目的。
答案 1 :(得分:-1)
您应该创建一个函数以获取最旧的查询,而无需输入数字,例如:
SELECT * FROM tablename WHERE number IS NULL ORDER BY ds ASC
然后再次查询获得最大号码的地方:
SELECT * FROM tablename ORDER BY number DESC
然后,如果两个查询具有相同的日期,则使用相同的编号更新表:
UPDATE tablename SET number = 'greatest number from first query' WHERE ds = 'the date from first query'
或如果日期不同,则相同,但将数字加1:
UPDATE tablename SET number= 'greatest number from first query' + 1 WHERE ds = 'the date from first query'
要执行此操作,您应该首先将数字1与最早的条目关联。 您应该循环执行此操作,直到第一个查询(检查是否有未设置的任何数字)为空。 第一个查询假设空列全为空,如果是另一种情况,则应更改WHERE条件以检查该列何时为空。