Apache spark 以迭代方式保存到Pyspark中的新数据帧
我正在基于3个不同的PySpark数据帧执行计算 这个脚本的工作原理是按照它应该的方式执行计算,但是,我很难正确处理所述计算的结果 导入系统 将numpy作为np导入 从pyspark导入SparkConf、SparkContext、SQLContext sc=SparkContext(“本地”) sqlContext=sqlContext(sc) #虚拟数据 df=sqlContext.createDataFrame([[0,1,0,0,0],[1,1,0,0,1],[0,0,1,0,1],[1,0,1,1,0],[1,1,0,0,0],[p1',p2',p3',p4',p5']) df.show() +---+---+---+---+---+ |p1 | p2 | p3 | p4 | p5| +---+---+---+---+---+ | 0| 1| 0| 0| 0| | 1| 1| 0| 0| 1| | 0| 0| 1| 0| 1| | 1| 0| 1| 1| 0| | 1| 1| 0| 0| 0| +---+---+---+---+---+ #价值观 values=sqlContext.createDataFrame([(0,1,'p1'),(无,1,'p2'),(0,0,'p3'),(无,0,'p4'),(1,无,'p5'),('f1','f2','index')) value.show() +----+----+-----+ |f1 | f2 |指数| +----+----+-----+ |0 | 1 | p1| |空| 1 | p2| |0 | 0 | p3| |空| 0 | p4| |1 |空| p5| +----+----+-----+ #砝码 权重=sqlContext.createDataFrame([(4,3,'p1'),(无,1,'p2'),(2,2,'p3'),(无,3,'p4'),(3,无,'p5'),('f1','f2','index')) 权重。显示() +----+----+-----+ |f1 | f2 |指数| +----+----+-----+ |4 | 3 | p1| |空| 1 | p2| |2 | 2 | p3| |空| 3 | p4| |3 |空| p5| +----+----+-----+ #函数:它将行值等于V的向量W求和,然后除以V的长度。 #如果行和V之间没有相似之处,则输出0 定义W_和(行、v、W): 如果len(w[row==v])>0: 返回浮动(np.sum(w[行==v])/len(w)) 其他: 返回0.0 对于数据中的每一列和每一行,应用上述函数Apache spark 以迭代方式保存到Pyspark中的新数据帧,apache-spark,pyspark,apache-spark-sql,spark-dataframe,pyspark-sql,Apache Spark,Pyspark,Apache Spark Sql,Spark Dataframe,Pyspark Sql,我正在基于3个不同的PySpark数据帧执行计算 这个脚本的工作原理是按照它应该的方式执行计算,但是,我很难正确处理所述计算的结果 导入系统 将numpy作为np导入 从pyspark导入SparkConf、SparkContext、SQLContext sc=SparkContext(“本地”) sqlContext=sqlContext(sc) #虚拟数据 df=sqlContext.createDataFrame([[0,1,0,0,0],[1,1,0,0,1],[0,0,1,0,1],[
#我们迭代值列(最后一个称为index的列除外)
对于值中的val。列[:-1]:
#我们对数据进行过滤,以便只处理为选定值定义的列
定义的_col=[i[0]表示值中的i。其中(F.col(val)>=0)。选择(values.index.collect()]
#我们只选择有用的列
df_select=df.select(定义的列)
#我们检索参考值和权重
V=np.array(values.where(values.index.isin(defined_col)).select(val.collect()).flatten()
W=np.array(weights.where(weights.index.isin(defined_col)).select(val.collect()).flatten()
W_sum_udf=F.udf(lambda行:W_sum(行,V,W),FloatType())
df_select.withColumn(val,W_sum_udf(F.array(*(F.col(x)表示df_select.columns中的x)))
这使得:
+---+---+---+---+---+---+
|p1 | p2 | p3 | p4 | p5 | f1|
+---+---+---+---+---+---+
| 0| 1| 0| 0| 0|2.0|
| 1| 1| 0| 0| 1|1.0|
| 0| 0| 1| 0| 1|2.0|
| 1| 0| 1| 1| 0|0.0|
| 1| 1| 0| 0| 0|0.0|
+---+---+---+---+---+---+
它按照我的要求将列添加到切片数据帧中。问题是,我宁愿将数据收集到一个新的数据中,以便在最后查看结果。在PySpark中是否有可能像我在pandas中那样(在某种程度上有效地)增长数据帧 编辑以使我的目标更清晰:
理想情况下,我会得到一个只包含计算列的数据帧,如下所示:
+---+---+
|f1 | f2|
+---+---+
|2.0|1.0|
|1.0|2.0|
|2.0|0.0|
|0.0|0.0|
|0.0|2.0|
+---+---+
您的问题有一些问题
首先,您的for
循环将产生错误,因为最后一行中的df_select
没有定义;最后也没有任务(它产生了什么?)
假设df_select
实际上是您的子样本
dataframe,在前面定义了一些行,并且您的最后一行类似于
new_df=subsample.withColumn(val,W_sum_udf(F.array(*(F.col(x)表示subsample.columns中的x)))
然后你的问题开始变得更清楚。自
值。列[:-1]
#['f1','f2']
整个循环的结果将是公正的
+--+--+--+--+--+--+--+
|p1 | p2 | p3 | p4 | f2 |
+---+---+---+---+---+
| 0| 1| 0| 0|1.0|
| 1| 1| 0| 0|2.0|
| 0| 0| 1| 0|0.0|
| 1| 0| 1| 1|0.0|
| 1| 1| 0| 0|2.0|
+---+---+---+---+---+
i、 e.仅包含列f2
(自然,因为带有f1
的结果被简单覆盖)
现在,正如我所说的,假设情况是这样的,并且您的问题实际上是如何将两列f1
和f2
放在一起,而不是放在不同的数据帧中,您可以忘记子样本
,将列附加到初始的df
,然后可能删除不需要的列:
init_cols=df.columns
初始化
#['p1','p2','p3','p4','p5']
新的_df=df
对于值中的val。列[:-1]:
#我们对数据进行过滤,以便只处理为选定值定义的列
定义的_col=[i[0]表示值中的i。其中(F.col(val)>=0)。选择(values.index.collect()]
#我们检索参考值和权重
V=np.array(values.where(values.index.isin(defined_col)).select(val.collect()).flatten()
W=np.array(weights.where(weights.index.isin(defined_col)).select(val.collect()).flatten()
W_sum_udf=F.udf(lambda行:W_sum(行,V,W),FloatType())
new_df=new_df.with column(val,W_sum_udf(F.array(*(F.col(x)表示定义的_col中的x)))#在此处更改
#删除初始列:
对于i in init_cols:
新建测向=新建测向下降(i)
产生的new_df
将是:
+--+--+
|f1 | f2 |
+---+---+
|2.0|1.0|
|1.0|2.0|
|2.0|0.0|
|0.0|0.0|
|0.0|2.0|
+---+---+
更新(注释后):要强制W_sum
函数中的除法为浮点数,请使用:
来自未来进口部的
new_df
现在将是:
+-----------+----------+
|f1 | f2|
+---------+----+