计算并比较两列的平均值
Compute and compare the average of two columns
我开始将我的 Pandas 实现转换为 pySpark,但我在执行一些基本操作时遇到了问题。所以我有这个 table:
+-----+-----+----+
| Col1|Col2 |Col3|
+-----+-----+----+
| 1 |[1,3]| 0|
| 44 |[2,0]| 1|
| 77 |[1,5]| 7|
+-----+-----+----+
我想要的输出是:
+-----+-----+----+----+
| Col1|Col2 |Col3|Col4|
+-----+-----+----+----+
| 1 |[1,3]| 0|2.67|
| 44 |[2,0]| 1|2.67|
| 77 |[1,5]| 7|2.67|
+-----+-----+----+----+
到达这里:
- 我对 Col2 中每个数组的第一项进行平均,并对 Col2 中每个数组的第二项进行平均。由于第二个“子列”的平均值 ((3+0+5)/3) 大于第一个“子列”的 ((1+2+1)/3) 这是“获胜”条件.之后,我创建了一个新列,其中复制了 table 行数的“获胜”平均值(在本例中为 3)。
我已经能够通过“手动”选择 ta 列来做到这一点,对其进行平均,然后使用“点亮”来复制结果。我的实现的问题是 collect() 需要很多时间并且不推荐 afaik。
你能帮我解决这个问题吗?
您可以使用 greatest
获取数组中每个(子)列的最大平均值:
from pyspark.sql import functions as F, Window
df2 = df.withColumn(
'Col4',
F.greatest(*[F.avg(F.udf(lambda r: [float(i) for i in r.toArray()], 'array<double>')('Col2')[i]).over(Window.orderBy()) for i in range(2)])
)
df2.show()
+----+------+----+------------------+
|Col1| Col2|Col3| Col4|
+----+------+----+------------------+
| 1|[1, 3]| 0|2.6666666666666665|
| 44|[2, 0]| 1|2.6666666666666665|
| 77|[1, 5]| 7|2.6666666666666665|
+----+------+----+------------------+
如果你希望数组大小是动态的,你可以这样做
arr_size = df.select(F.max(F.size(F.udf(lambda r: [float(i) for i in r.toArray()], 'array<double>')('Col2')))).head()[0]
df2 = df.withColumn(
'Col4',
F.greatest(*[F.avg(F.udf(lambda r: [float(i) for i in r.toArray()], 'array<double>')('Col2')[i]).over(Window.orderBy()) for i in range(arr_size)])
)
我开始将我的 Pandas 实现转换为 pySpark,但我在执行一些基本操作时遇到了问题。所以我有这个 table:
+-----+-----+----+
| Col1|Col2 |Col3|
+-----+-----+----+
| 1 |[1,3]| 0|
| 44 |[2,0]| 1|
| 77 |[1,5]| 7|
+-----+-----+----+
我想要的输出是:
+-----+-----+----+----+
| Col1|Col2 |Col3|Col4|
+-----+-----+----+----+
| 1 |[1,3]| 0|2.67|
| 44 |[2,0]| 1|2.67|
| 77 |[1,5]| 7|2.67|
+-----+-----+----+----+
到达这里:
- 我对 Col2 中每个数组的第一项进行平均,并对 Col2 中每个数组的第二项进行平均。由于第二个“子列”的平均值 ((3+0+5)/3) 大于第一个“子列”的 ((1+2+1)/3) 这是“获胜”条件.之后,我创建了一个新列,其中复制了 table 行数的“获胜”平均值(在本例中为 3)。 我已经能够通过“手动”选择 ta 列来做到这一点,对其进行平均,然后使用“点亮”来复制结果。我的实现的问题是 collect() 需要很多时间并且不推荐 afaik。 你能帮我解决这个问题吗?
您可以使用 greatest
获取数组中每个(子)列的最大平均值:
from pyspark.sql import functions as F, Window
df2 = df.withColumn(
'Col4',
F.greatest(*[F.avg(F.udf(lambda r: [float(i) for i in r.toArray()], 'array<double>')('Col2')[i]).over(Window.orderBy()) for i in range(2)])
)
df2.show()
+----+------+----+------------------+
|Col1| Col2|Col3| Col4|
+----+------+----+------------------+
| 1|[1, 3]| 0|2.6666666666666665|
| 44|[2, 0]| 1|2.6666666666666665|
| 77|[1, 5]| 7|2.6666666666666665|
+----+------+----+------------------+
如果你希望数组大小是动态的,你可以这样做
arr_size = df.select(F.max(F.size(F.udf(lambda r: [float(i) for i in r.toArray()], 'array<double>')('Col2')))).head()[0]
df2 = df.withColumn(
'Col4',
F.greatest(*[F.avg(F.udf(lambda r: [float(i) for i in r.toArray()], 'array<double>')('Col2')[i]).over(Window.orderBy()) for i in range(arr_size)])
)