#python #apache-spark #pyspark #apache-spark-sql
#apache-spark #pyspark #apache-spark-sql #null #совокупный
Вопрос:
У меня есть случай, когда у меня могут быть нулевые значения в столбце, которые необходимо суммировать в группе.
Если я сталкиваюсь с null в группе, я хочу, чтобы сумма этой группы была равна null. Но PySpark по умолчанию, похоже, игнорирует нулевые строки и суммирует остальные ненулевые значения.
Например:
dataframe = dataframe.groupBy('dataframe.product', 'dataframe.price')
.agg(f.sum('price'))
Ожидаемый результат:
Но я получаю:
Ответ №1:
sum
функция возвращает NULL, только если все значения для этого столбца равны null, в противном случае null просто игнорируются.
Вы можете использовать условную агрегацию, если count(price) == count(*)
это означает, что нет нулей, и мы возвращаемся sum(price)
. В противном случае возвращается значение null:
from pyspark.sql import functions as F
df.groupby("product").agg(
F.when(F.count("price") == F.count("*"), F.sum("price")).alias("sum_price")
).show()
# ------- ---------
#|product|sum_price|
# ------- ---------
#| B| 200|
#| C| null|
#| A| 250|
# ------- ---------
Начиная с Spark 3.0 , можно также использовать any
функцию:
df.groupby("product").agg(
F.when(~F.expr("any(price is null)"), F.sum("price")).alias("sum_price")
).show()
Ответ №2:
Вы можете заменить NULL на NAN с помощью coalesce
:
df2 = df.groupBy('product').agg(
F.sum(
F.coalesce(F.col('price'), F.lit(float('nan')))
).alias('sum(price)')
).orderBy('product')
df2.show()
------- ----------
|product|sum(price)|
------- ----------
| A| 250.0|
| B| 200.0|
| C| NaN|
------- ----------
Если вы хотите сохранить целочисленный тип, вы можете преобразовать NAN обратно в null с помощью nanvl
:
df2 = df.groupBy('product').agg(
F.nanvl(
F.sum(
F.coalesce(F.col('price'), F.lit(float('nan')))
),
F.lit(None)
).cast('int').alias('sum(price)')
).orderBy('product')
df2.show()
------- ----------
|product|sum(price)|
------- ----------
| A| 250|
| B| 200|
| C| null|
------- ----------