首页 > 解决方案 > Pyspark 按表达式对数据帧进行排序

问题描述

我目前正在阅读Spark the definitive guide,并且有一个orderBy使用 an 的 DataFrame示例,expr但它不起作用:

from pyspark.sql.types import *
from pyspark.sql.functions import *
from pyspark.sql import Row

schema = StructType([
  StructField("origin", StringType(), True),
  StructField("destination", StringType(), True),
  StructField("count", LongType(), True)
])

rows = [
  Row("US", "Germany", 5),
  Row("US", "France", 1),
  Row("US", "UK", 10)
]

parallelizedRows = spark.sparkContext.parallelize(rows)
df = spark.createDataFrame(parallelizedRows, schema)

descending现在,为了使用顺序对 DataFrame 进行排序expr

df.orderBy(expr("count desc")).show(3)

输出仍在ascending. 但它使用Column类工作:

df.orderBy(col("count").desc()).show(3)

知道为什么expr不工作吗?

标签: pythondataframeapache-sparkpyspark

解决方案


如果您在沙盒环境中工作,例如笔记本,请尝试以下操作:

import pyspark.sql.functions as f

f.expr("count desc")

这会给你

Column<b'count AS `desc`'>

这意味着您按count别名为的列排序desc,本质上是按f.col("count").alias("desc"). 我不确定为什么 中不存在此功能expr(),但我相信这是因为您还有其他几个选项可以执行此操作,例如:

df.orderBy(f.col("count").desc())
df.orderBy(f.col("count"), ascending=False)
df.orderBy(f.desc("count"))

每个都将返回以下内容:

>>> f.desc("count")
Column<b'count DESC NULLS LAST'>

话虽如此,如果您将您DataFrame的表注册为表并sqlContext.sql(...)对其运行查询,您将能够运行ANSI SQL查询,ORDER BY COUNT DESC;最后它会起作用。

作为旁注,请尽量不要使用from pyspark.sql.functions import *,原因有两个:

  1. 如果您可以在别名下导入模块,那么从模块中导入所有内容绝不是一个好主意
  2. pyspark.sql.functions.sum在这种特定情况下,您正在导入诸如as之类的东西,sum它会覆盖本机 python 库函数,从而导致稍后在代码中出现烦人且难以调试的错误。

推荐阅读