[英]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.