[英]Using pandas udf without looping in pyspark
所以假设我有一个大火花 dataframe。我不知道有多少列。
(解决方案必须在 pyspark 中使用 pandas udf。不是不同的方法)
我想对所有列执行操作。 所以可以在所有列中循环但我不想遍历行。 我希望它立即作用于列。
我没有在 inte.net 上找到如何做到这一点。
假设我有这个数据框
A B C
5 3 2
1 7 0
现在我想发送到 pandas udf 以获取每一行的总和。
Sum
10
8
列数未知。
我可以通过一次循环行在 udf 中完成它。 但我不想。 我希望它在不循环的情况下作用于所有行。 如果需要,我允许循环遍历列。
我尝试过的一种选择是将所有列组合到数组列
ARR
[5,3,2]
[1,7,0]
但即使在这里,如果没有循环,它对我也不起作用。 我将此列发送到 udf,然后在内部我需要遍历它的行并对列表行的每个值求和。
如果我可以将每一列分开并立即对整个列进行操作,那就太好了
我如何立即对列进行操作? 不遍历行?
如果我遍历这些行,我猜它并不比普通的 python udf 好
我不会从 go 到 pandas udfs,求助于 udfs 它不能在 pyspark 中完成。无论如何下面的代码
df = spark.read.load('/databricks-datasets/asa/small/small.csv', header=True,format='csv')
sf = df.select(df.colRegex("`.*rrDelay$|.*pDelay$`"))
#sf.show()
columns = ["id","ArrDelay","DepDelay"]
data = [("a", 81.0,3),
("b", 36.2,5),
("c", 12.0,5),
("d", 81.0,5),
("e", 36.3,5),
("f", 12.0,5),
("g", 111.7,5)]
sf = spark.createDataFrame(data=data,schema=columns)
sf.show()
# Use aggregate function
new = (sf.withColumn('sums', array(*[x for x in ['ArrDelay','DepDelay'] ]))#Create an array of values per row on desired columns
.withColumn('sums', expr("aggregate(sums,cast(0 as double), (c,i)-> c+i)"))# USE aggregate to sum
).show()
#use pandas udf
sch= sf.withColumn('v', lit(90.087654623)).schema
def sum_s(iterator: Iterator[pd.DataFrame]) -> Iterator[pd.DataFrame]:
for pdf in iterator:
yield pdf.assign(v=pdf.sum(1))
sf.mapInPandas(sum_s, schema=sch).show()
这是一个简单的方法
from pyspark.sql import functions as F
from pyspark.sql.types import *
from pyspark.sql import Window
from functools import reduce
df = spark.createDataFrame(
[
(5,3,2),
(1,7,0),
],
["A", "B", "C"],
)
cols = df.columns
calculate_sum = reduce(lambda a, x: a+x, map(col, cols))
df = (
df
.withColumn(
"sum",calculate_sum
)
)
df.show()
output:
+---+---+---+---+
| A| B| C|sum|
+---+---+---+---+
| 5| 3| 2| 10|
| 1| 7| 0| 8|
+---+---+---+---+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.