Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PySpark-使用多列作为键填充缺少的数据_Python_Apache Spark_Pyspark - Fatal编程技术网

Python PySpark-使用多列作为键填充缺少的数据

Python PySpark-使用多列作为键填充缺少的数据,python,apache-spark,pyspark,Python,Apache Spark,Pyspark,我有一个4列的spark数据框 ts -> long (unix timestamp) col1 -> string col2 -> string value -> long ts、col1和col2的组合在我的数据中是独一无二的。我想通过创建包含缺失ts的行来填充缺失的数据,col1和col2包含前3列的所有组合ts有一个特定的范围,col1和col2有一个离散的值列表。我能想到的唯一方法是创建一个包含3列的所有有效组合的新数据帧,并将值列设置为0,然后以某种方式合并

我有一个4列的spark数据框

ts -> long (unix timestamp)
col1 -> string
col2 -> string
value -> long
ts、col1和col2的组合在我的数据中是独一无二的。我想通过创建包含缺失ts的行来填充缺失的数据,col1和col2包含前3列的所有组合ts有一个特定的范围,col1和col2有一个离散的值列表。我能想到的唯一方法是创建一个包含3列的所有有效组合的新数据帧,并将值列设置为0,然后以某种方式合并2个数据帧。 这就是我目前所拥有的

partial_data_df = spark.read.csv(my_path)

TS_DF = spark.range(min_ts, max_ts, 1000 * 3600).select(F.col('id').alias('ts')).orderBy('ts')
COL1_DF = spark.createDataFrame([..some data..], schema=['col1'])
COL2_DF = spark.createDataFrame([..some data..], schema=['col2'])
EMPTY_DF = TS_DF.crossJoin(COL1_DF).crossJoin(COL2_DF).withColumn('value', F.lit(0))

# now what?
如何在3列上合并部分数据和空数据,以便如果组合存在,则从部分数据中获取值列,如果不存在,则输入0?有没有其他更优雅的方式来实现这一点

编辑

我试着像这样做一个左连接,所以我按照建议从空的_DF中删除了value列

merged_df = EMPTY_DF.join(partial_data_df, (
                     (partial_data_df.ts == EMPTY_DF.ets) & 
                     (partial_data_df.col1 == EMPTY_DF.ecol1) &
                     (partial_data_df.col2 == EMPTY_DF.ecol2)
                    ), how='left')
         .select(
           F.col('ets').alias('ts'), 
           F.col('ecol1').alias('col1'), 
           F.col('ecol2').alias('col2'),
           F.when(((F.col('value').isNull()) | (F.col('value') == 0)), 0).otherwise(F.col('value')).alias('value')
         )
但行数没有加起来

row count in EMPTY_DF is 778176
row count in partial_data_df is 131709
row count in merged_df 778176
row count in merged_df that has non zero volume 100348
row count in partial_data_df that has non zero volume 131709
count distinct (ts, col1, col2) on partial_data_df 131709
count distinct (ts, col1, col2) on merged_df 778176

这里出了什么问题?

您可以使用

方法1 …表别名和when函数,以使用原始数据帧中的值(如果可用)。使用这种方法,您不需要在内存中使用.withColumn'value',F.lit0生成所有可能的空值,因为交叉连接将导致我们可以使用的空值

从pyspark.sql.functions导入时,col partial_data_df=partial_data_df.别名'original_df' EMPTY_DF=EMPTY_DF.别名'EMPTY_DF' 最终_df=空_df.join部分_数据_df, col'original_df.ts'==col'empty_df.ts'& col'original_df.col1'==col'empty_df.col1'& col'original_df.col2'==col'empty_df.col2'& ,左。选择 col'original_df.ts', col'original_df.col1', col'original_df.col2', 当col'original_df.value'。为空时,为0。否则col'original_df.value'。别名为'value' 或者因为两列都存在于两个数据帧中 final_df=EMPTY_df.joinpartial_data_df,['ts','col1','col2',],left.select col'empty_df.ts', col'empty_df.col1', col'empty_df.col2', 当col'original_df.value'。为空时,为0。否则col'original_df.value'。别名为'value' 方法2 另一种方法是使用spark sql

partial_data_df=partial_data_df.createOrReplaceTempView'original_df' EMPTY_DF=EMPTY_DF.createOrReplaceTempView'EMPTY_DF' final_df=sparkSession.sql 选择 e、 ts, e、 col1, e、 col2, 案例 当o.value为空时,则为0 否则,你的价值 作为价值结束 从…起 空的 左连接 o.ts上的原始_df o=e.ts和 o、 col1=e.col1和 o、 col2=e.col2 工具书类
谢谢-我试着用我的代码编辑OP,但最终的行数不匹配。我得到合并的_-df具有空的_-df的精确行数,这是预期的且良好的,但是值列中非0值的行数小于部分_数据的行数。知道为什么吗?非零值部分数据的行数是多少?@ggordon-请查看问题中更新的行数-有点不正确-可能是某些实际值与生成的值不匹配,例如,如果您的一个实际ts值在一小时后1秒。当modvalue、1000*3600=0然后0 ELSE 1结束时,您能否使用partial_data_df.selectF.exprCASE确认这些值是否存在。别名“不一致”。aggF.sum“不一致”。