在PySpark中,有没有办法对dataframe执行与将分区映射到rdd相同的操作?

在PySpark中,有没有办法对dataframe执行与将分区映射到rdd相同的操作?,dataframe,pyspark-sql,Dataframe,Pyspark Sql,我想对数据帧应用一个函数。该函数将返回该行和它前面的行数的平均值,这样,由于回望的存在,最终结果的行数将与原始数据帧不同。现在我使用mapPartition来实现这一点。但是,我是否可以返回相同的内容,但直接对数据帧本身进行计算,而不需要将其传输回rdd original dataframe: +-----+-------+---+---+ |group|row_num|cnt|val| +-----+-------+---+---+ | 1| 1| 4| 1| | 1

我想对数据帧应用一个函数。该函数将返回该行和它前面的行数的平均值,这样,由于回望的存在,最终结果的行数将与原始数据帧不同。现在我使用mapPartition来实现这一点。但是,我是否可以返回相同的内容,但直接对数据帧本身进行计算,而不需要将其传输回rdd

original dataframe:
+-----+-------+---+---+
|group|row_num|cnt|val|
+-----+-------+---+---+
|    1|      1|  4|  1|
|    1|      2|  4|  2|
|    1|      3|  4|  3|
|    1|      4|  4|  4|
|    2|      1|  4|  5|
|    2|      2|  4|  6|
|    2|      3|  4|  7|
|    2|      4|  4|  8|
+-----+-------+---+---+

from pyspark import SparkContext
from pyspark.sql import SparkSession
from pyspark.sql.types import *

def mean(rows):
    res = []
    val = []
    row_num = []
    for row in rows:
        print row.val
        if row.row_num == 1:
            val = []
            row_num = []
        val.append(row.val)
        row_num.append(row.row_num)
        if row.row_num == row.cnt:
            results = cal(val)
            #print results
            index = -1
            for item in results[::-1]:
                res.append((row.group, row_num[index], item))
                index = index - 1
    return res

def cal(val):
    res = []
    for i in range(1, len(val)):
        res.append((val[i] + val[i - 1]) / 2)
    return res


sc = SparkContext()
spark = SparkSession(sc)
rdd = sc.parallelize([(1, 1, 4, 1), (1, 2, 4, 2), (1, 3, 4, 3), (1, 4, 4, 4),
                      (2, 1, 4, 5), (2, 2, 4, 6), (2, 3, 4, 7), (2, 4, 4, 8)])
scheme = StructType([
    StructField("group", IntegerType(), False),
    StructField("row_num", IntegerType(), False),
    StructField("cnt", IntegerType(), False),
    StructField("val", IntegerType(), False)
])
df = spark.createDataFrame(rdd, scheme)
df = df.repartition("group")

rdd_new = df.rdd.mapPartitions(mean)
scheme_new = StructType([
    StructField("group", IntegerType(), False),
    StructField("row_num", IntegerType(), False),
    StructField("mean", IntegerType(), False)
])
df_new = spark.createDataFrame(rdd_new, scheme_new)
df_new.show()

the output I want:
+-----+-------+----+
|group|row_num|mean|
+-----+-------+----+
|    1|      4|   3|
|    1|      3|   2|
|    1|      2|   1|
|    2|      4|   7|
|    2|      3|   6|
|    2|      2|   5|
+-----+-------+----+

你探索过窗口功能吗?让您很好地了解如何使用它们。另外,看看这个问题,了解一个相关问题的更多细节:@Nanda你好,Nanda,我查看了关于窗口函数的两个链接。是的,窗口函数是解决这个问题的一种思维方式。但在这里,我只发布了一个简单的计算平均值的方法,但我真正的计算是一个复杂的过程,计算了很多市场指标。那么,是否可以使用窗口函数来表示我的计算函数?PyPpark似乎不支持用户定义的窗口函数?我在PypSpark上的窗口函数也遇到了一些限制。如果不知道您需要哪些功能,我就无法回答您的问题。哦,我明白了。明白了,非常感谢您的帮助:)