PySpark列式绑定

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中是否有任何特定的方法可以像在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),[“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
    的工作方式不同。我将修改我的答案。但是,因为窗口函数是惰性计算的,所以测试计时并不那么直接。我想我可以用一个等效的
    过滤器来获得时间来显示数据帧()
    将窗口函数创建的列添加到数据帧之前和之后。