PySpark列式绑定
在PySpark中是否有任何特定的方法可以像在r中一样cbind两个数据帧 例如:PySpark列式绑定,pyspark,Pyspark,在PySpark中是否有任何特定的方法可以像在r中一样cbind两个数据帧 例如: 数据框1有10列 数据帧2有一列 我需要在PySpark中查找数据帧并使其成为一个数据帧。首先,让我们创建数据帧: df1=spark.createDataFrame(sc.parallelize([10*[c]表示范围(10)])中的c,[“c”+str(i)表示范围(10)]) df2=spark.createDataFrame(sc.parallelize([[c]表示范围(10,20,1)])内的c),
我需要在PySpark中查找数据帧并使其成为一个数据帧。首先,让我们创建数据帧:
df1=spark.createDataFrame(sc.parallelize([10*[c]表示范围(10)])中的c,[“c”+str(i)表示范围(10)])
df2=spark.createDataFrame(sc.parallelize([[c]表示范围(10,20,1)])内的c),[“c10”])
+---+---+---+---+---+---+---+---+---+---+
|c0 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9|
+---+---+---+---+---+---+---+---+---+---+
| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|
| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1|
| 2| 2| 2| 2| 2| 2| 2| 2| 2| 2|
| 3| 3| 3| 3| 3| 3| 3| 3| 3| 3|
| 4| 4| 4| 4| 4| 4| 4| 4| 4| 4|
| 5| 5| 5| 5| 5| 5| 5| 5| 5| 5|
| 6| 6| 6| 6| 6| 6| 6| 6| 6| 6|
| 7| 7| 7| 7| 7| 7| 7| 7| 7| 7|
| 8| 8| 8| 8| 8| 8| 8| 8| 8| 8|
| 9| 9| 9| 9| 9| 9| 9| 9| 9| 9|
+---+---+---+---+---+---+---+---+---+---+
+---+
|c10|
+---+
| 10|
| 11|
| 12|
| 13|
| 14|
| 15|
| 16|
| 17|
| 18|
| 19|
+---+
然后我们想要唯一地标识行,有一个用于RDD
的函数可以实现这一点zipWithIndex
从pyspark.sql.types导入LongType
从pyspark.sql导入行
def zipindexdf(df):
schema_new=df.schema.add(“index”,LongType(),False)
返回df.rdd.zipWithIndex().map(lambda l:list(l[0])+[l[1]]).toDF(schema_new)
df1_索引=zipindexdf(df1)
df1_index.show()
df2_索引=zipindexdf(df2)
df2_index.show()
+---+---+---+---+---+---+---+---+---+---+-----+
|c0 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 |指数|
+---+---+---+---+---+---+---+---+---+---+-----+
| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|
| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1|
| 2| 2| 2| 2| 2| 2| 2| 2| 2| 2| 2|
| 3| 3| 3| 3| 3| 3| 3| 3| 3| 3| 3|
| 4| 4| 4| 4| 4| 4| 4| 4| 4| 4| 4|
| 5| 5| 5| 5| 5| 5| 5| 5| 5| 5| 5|
| 6| 6| 6| 6| 6| 6| 6| 6| 6| 6| 6|
| 7| 7| 7| 7| 7| 7| 7| 7| 7| 7| 7|
| 8| 8| 8| 8| 8| 8| 8| 8| 8| 8| 8|
| 9| 9| 9| 9| 9| 9| 9| 9| 9| 9| 9|
+---+---+---+---+---+---+---+---+---+---+-----+
+---+-----+
|c10指数|
+---+-----+
| 10| 0|
| 11| 1|
| 12| 2|
| 13| 3|
| 14| 4|
| 15| 5|
| 16| 6|
| 17| 7|
| 18| 8|
| 19| 9|
+---+-----+
最后,我们可以加入他们:
df=df1\u index.join(df2\u索引,“索引”,“内部”)
+-----+---+---+---+---+---+---+---+---+---+---+---+
|指数| c0 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10|
+-----+---+---+---+---+---+---+---+---+---+---+---+
| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 10|
| 7| 7| 7| 7| 7| 7| 7| 7| 7| 7| 7| 17|
| 6| 6| 6| 6| 6| 6| 6| 6| 6| 6| 6| 16|
| 9| 9| 9| 9| 9| 9| 9| 9| 9| 9| 9| 19|
| 5| 5| 5| 5| 5| 5| 5| 5| 5| 5| 5| 15|
| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 11|
| 3| 3| 3| 3| 3| 3| 3| 3| 3| 3| 3| 13|
| 8| 8| 8| 8| 8| 8| 8| 8| 8| 8| 8| 18|
| 2| 2| 2| 2| 2| 2| 2| 2| 2| 2| 2| 12|
| 4| 4| 4| 4| 4| 4| 4| 4| 4| 4| 4| 14|
+-----+---+---+---+---+---+---+---+---+---+---+---+
要获得ID单调递增、唯一且连续的列,请在每个数据帧上使用以下内容,其中colName
是要按其对每个数据帧进行排序的列名
import pyspark.sql.functions as F
from pyspark.sql.window import Window as W
window = (
W.partitionBy(F.lit(0))
.orderBy('colName')
.rowsBetween(W.unboundedPreceding, W.currentRow)
)
df = (df
.withColumn('int', F.lit(1))
.withColumn('consec_id', F.sum('int').over(window))
.drop('int')
)
要检查所有内容是否正确排列,请使用以下代码查看数据帧的尾部或最后一个rownums
rownums = 10
df.where(F.col('consec_id')>df.count()-rownums).show()
start_row = 20
end_row = 30
df.where((F.col('consec_id')>start_row) & (F.col('consec_id')<end_row)).show()
使用以下代码查看数据帧的start\u row
到end\u row
之间的行
rownums = 10
df.where(F.col('consec_id')>df.count()-rownums).show()
start_row = 20
end_row = 30
df.where((F.col('consec_id')>start_row) & (F.col('consec_id')<end_row)).show()
[“59.813秒”,
“39.574秒”,
“36.074秒”,
“35.436秒”,
“35.636秒”]
import time
import pyspark.sql.functions as F
from pyspark.sql.window import Window as W
def test_win(df):
startTime = time.time()
window = W.orderBy('colName').rowsBetween(W.unboundedPreceding, W.currentRow)
df_2 = df \
.withColumn('int', F.lit(1)) \
.withColumn('IDcol', F.sum('int').over(window)) \
.drop('int')
start_row = 20000
end_row = 20010
df_2.where((F.col('consec_id')>start_row) & (F.col('consec_id')<end_row)).show()
endTime = time.time() - startTime
return str(round(endTime,3)) + " seconds"
[test_win(df) for _ in range(5)]
import time
from pyspark.sql.types import StructType, StructField
import pyspark.sql.types as T
def test_zip2(df):
startTime = time.time()
schema_new = StructType(list(df.schema) + [StructField("consec_id", T.LongType(), False)])
df_3 = df.rdd.zipWithIndex().map(lambda l: list(l[0]) + [l[1]]).toDF(schema_new)
start_row = 20000
end_row = 20010
df_3.where((F.col('IDcol')>start_row) & (F.col('consec_id')<end_row)).show()
endTime = time.time() - startTime
return str(round(endTime,3)) + " seconds"
[test_zip2(testdf) for _ in range(5)]
导入时间
导入pyspark.sql.F函数
从pyspark.sql.window导入窗口为W
def测试(df):
startTime=time.time()
window=W.orderBy('colName')。中间的行(W.unbounddpreceiding,W.currentRow)
df_2=df\
.带列('int',F.lit(1))\
.withColumn('IDcol',F.sum('int')。在(窗口)上方)\
.drop('int')
起始行=20000
end_行=20010
df_2.其中((F.col('concer_id')>start_row)&(F.col('concer_id')start_row)&(F.col('concer_id'))这不适用于可能跨不同分区存储的两个单独的大数据帧,并且每个数据帧在不同行上的分区之间分开当前的实现将分区ID放在上面的31位,每个分区内的记录号放在下面的33位。"你说得对,我简直不敢相信我写的是,单调递增ID的计数对每个任务都有不同的来源经常引用的rdd函数zipwithindex
的工作方式是相同的。zipwithindex
是指定的行枚举方法。在整个数据帧上使用窗口函数效率极低。我鼓励您测试它并使用%timeit.Now您是对的。zipWithIndex
的工作方式不同。我将修改我的答案。但是,因为窗口函数是惰性计算的,所以测试计时并不那么直接。我想我可以用一个等效的过滤器来获得时间来显示数据帧()
将窗口函数创建的列添加到数据帧之前和之后。