我需要在标识符和条件上合并两个数据帧,其中一个数据帧中的日期在另一个数据帧中的两个日期之间,并在另一列中进行groupby(计算总和)
数据框A具有日期(“日期”),数字(“数字”)和ID(“ id”):
| id | date | number |
| 101 | 2018-12-01 | 250 |
| 101 | 2018-12-02 | 150 |
| 102 | 2018-11-25 | 1000 |
| 102 | 2018-10-26 | 2000 |
| 102 | 2018-09-25 | 5000 |
| 103 | 2018-10-26 | 200 |
| 103 | 2018-10-27 | 2000 |
数据框B具有Id(“ id”),fromdate(“ fromdate”)和todate(“ todate”):
| id | fromdate | todate |
| 101 | 2018-10-01 | 2018-11-01 |
| 101 | 2018-11-02 | 2018-12-30 |
| 102 | 2018-09-01 | 2018-09-30 |
| 102 | 2018-10-01 | 2018-12-31 |
| 103 | 2018-10-01 | 2018-10-30 |
| 104 | 2018-10-01 | 2018-10-30 |
现在,我需要将这两个数据框的id和date合并,然后将所有数字相加。 例如: 考虑数据框B中的第四行,对于id 102,在这些日期之间,我们有两个对应的行(行#3,4)来自数据框Am,通过计算总和来合并它们。
所以结果行将是
| id | fromdate | todate | sum |
| 102 | 2018-10-01 | 2018-12-31 | 3000 |
最终结果应为: | id | fromdate |至今总和|
| 101 | 2018-10-01 | 2018-11-01 | 0 |
| 101 | 2018-11-02 | 2018-12-30 | 400 |
| 102 | 2018-09-01 | 2018-09-30 | 5000 |
| 102 | 2018-10-01 | 2018-12-31 | 3000 |
| 103 | 2018-10-01 | 2018-10-30 | 2200 |
| 104 | 2018-10-01 | 2018-10-30 | 0 |
答案 0 :(得分:2)
这是您可以遵循的详细方法-
from pyspark.sql.types import *
################
##Define Schema
################
schema1 = StructType([StructField('id', IntegerType(), True),
StructField('date', StringType(), True),
StructField('number', IntegerType(), True)
]
)
schema2 = StructType([StructField('id', IntegerType(), True),
StructField('fromdate', StringType(), True),
StructField('todate', StringType(), True)
]
)
################
##Prepare Data
################
data1 = [
(101,'2018-12-01',250 ),
(101,'2018-12-02',150 ),
(102,'2018-11-25',1000),
(102,'2018-10-26',2000),
(102,'2018-09-25',5000),
(103,'2018-10-26',200 ),
(103,'2018-10-27',2000)
]
data2 = [
(101,'2018-10-01','2018-11-01'),
(101,'2018-11-02','2018-12-30'),
(102,'2018-09-01','2018-09-30'),
(102,'2018-10-01','2018-12-31'),
(103,'2018-10-01','2018-10-30'),
(104,'2018-10-01','2018-10-30')
]
################
##Create dataframe and type cast to date
################
df1 = spark.createDataFrame(data1, schema1)
df2 = spark.createDataFrame(data2, schema2)
df1 = df1.select(df1.id,df1.date.cast("date"),df1.number)
df2 = df2.select(df2.id,df2.fromdate.cast("date"),df2.todate.cast("date"))
定义联接条件并联接数据框
################
##Define Joining Condition
################
cond = [df1.id == df2.id, df1.date.between(df2.fromdate,df2.todate)]
################
##Join dataframes using joining condition "cond" and aggregation
################
from pyspark.sql.functions import coalesce
df2.\
join(df1, cond,'left').\
select(df2.id,df1.number,df2.fromdate,df2.todate).\
groupBy('id','fromdate','todate').\
sum('number').fillna(0).\
show()