如何通过替换pyspark中的for循环来优化代码?

7tofc5zh  于 2024-01-06  发布在  Spark
关注(0)|答案(2)|浏览(176)

我必须在我的 Dataframe 中的所有列上实现下面的函数。但是使用for循环对spark性能有害,我如何避免使用for循环而仍然具有相同的逻辑和输出?我的函数接受一个 Dataframe ,并返回一个 Dataframe ,其中包含每个列的列名和所需的统计信息。
函数如下:

  1. def get_null_count_and_percentage(df):
  2. columnList = df.columns
  3. total_count = df.count()
  4. null_counts = []
  5. for column_to_check in columnList:
  6. null_count = df.filter(col(column_to_check).isNull()).count()
  7. null_perentage = (null_count / total_count) * 100
  8. null_counts.append((column_to_check, null_count, null_perentage))
  9. result_df_count = (
  10. spark.createDataFrame(null_counts, ["column_name", "null_counts", "null_percentage"])
  11. .withColumn("null_percentage", round(col("null_percentage"), 3))
  12. )
  13. return result_df_count

字符串
我试着去找,但是找不到我的问题的确切解决方案。我试过map,reduce等,但是这些都不能解决这个问题。

iih3973s

iih3973s1#

下面的代码将获得所有列的空计数

  1. from pyspark.sql.functions import when, count, col
  2. df.select([count(when(col(c).isNull(), c)).alias(c) for c in df.columns]).show()

字符串

lsmepo6l

lsmepo6l2#

你可以把它简化成这样。首先计算你需要的任何stats并将其分配给struct(以避免重复的for循环)。然后使用stack将列转置为行,然后从struct中提取stats列。参见下面的例子:

  1. from pyspark.sql.functions import count, struct, round
  2. data = [
  3. (1, "John", 25, None, "Male"),
  4. (2, "Jane", None, 5000, "Female"),
  5. (3, "Bob", 30, 6000, None),
  6. (4, None, 35, 7000, "Male"),
  7. (5, "Alice", 40, 8000, "Female"),
  8. ]
  9. # Define the schema for the DataFrame
  10. columns = ["ID", "Name", "Age", "Salary", "Gender"]
  11. # Create a DataFrame with null values
  12. df = spark.createDataFrame(data, columns)
  13. df.agg(
  14. *[
  15. struct(
  16. (count('*') - count(c)).alias('null_count'),
  17. round(((count('*') - count(c)) / count('*')) * 100, 2).alias('null_percentage')
  18. ).alias(f'{c}')
  19. for c in df.columns
  20. ]
  21. ).selectExpr(
  22. "stack(" + str(len(df.columns)) + ", " + ", ".join([f"'{c}', {c}" for c in df.columns]) + ") as (column_name, stats)"
  23. ).select(
  24. "column_name",
  25. "stats.null_count",
  26. "stats.null_percentage"
  27. ).show()
  28. Output:
  29. +-----------+----------+---------------+
  30. |column_name|null_count|null_percentage|
  31. +-----------+----------+---------------+
  32. | ID| 0| 0.0|
  33. | Name| 1| 0.2|
  34. | Age| 1| 0.2|
  35. | Salary| 1| 0.2|
  36. | Gender| 1| 0.2|
  37. +-----------+----------+---------------+

字符串

展开查看全部

相关问题