Apache spark PySpark SQL:用作表达式的子查询返回多行:

Apache spark PySpark SQL:用作表达式的子查询返回多行:,apache-spark,pyspark,apache-spark-sql,pyspark-sql,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Sql,我试图使用另一个名为train的数据帧中的值在测试数据帧中创建一个新列。下面是一个快照。在列车数据帧中,列aml_freq_a下第一行的值是v在列a中出现的次数。同样,aml_freq__b下的42是l在b中出现的次数。['aml_freq_a'、'aml_freq_b'、'aml_freq_c']基本上是频率列 >>> train.show(5) +---+---+---+----------+----------+----------+

我试图使用另一个名为train的数据帧中的值在测试数据帧中创建一个新列。下面是一个快照。在列车数据帧中,列aml_freq_a下第一行的值是v在列a中出现的次数。同样,aml_freq__b下的42是l在b中出现的次数。['aml_freq_a'、'aml_freq_b'、'aml_freq_c']基本上是频率列

>>> train.show(5)

+---+---+---+----------+----------+----------+                                  
|  a|  b|  c|aml_freq_a|aml_freq_b|aml_freq_c|
+---+---+---+----------+----------+----------+
|  v|  l|  l|        56|        42|        29|
|  u|  g|  l|        47|        46|        29|
|  s|  g|  l|        28|        46|        29|
|  v|  m|  l|        56|        33|        29|
|  h|  m|  l|        44|        33|        29|
+---+---+---+----------+----------+----------+
在测试数据集中有列['a'、'b'、'c']。在这里,我需要添加频率列-['aml\u freq\u a','aml\u freq\u b','aml\u freq\u c']

为此,我编写了子查询,将a、b和c上的train和test连接起来

spark.sqlquery运行良好,但当我调用show时,它会返回以下错误

java.lang.RuntimeException: more than one row returned by a subquery used as an expression:
这是什么意思?起初我认为我的查询有问题,但我验证了我的查询,这里没有问题。我在这里看不到什么?

意思是

您使用的相关子查询中至少有一个返回多个匹配项。 Spark只支持为每行返回一个值,即必须聚合相关子查询。 在您的尝试中,从测试时的测试左连接列中选择aml_freq_a。a=列。a将返回一个数据帧,即不能用作选择测试的选择参数的多行。*,从测试时的测试左连接列中选择aml_freq_a。a=列。a

正确的查询如下所示

query = "select test.* from " \
            "(select test.*, aml_freq_a from " \
                "(select test.*, aml_freq_b from " \
                    "(select test.*, aml_freq_c from test " \
                "left join train on test.c = train.c) as test " \
            "left join train on test.b = train.b)  as test " \
        "left join train on test.a = train.a) as test"
如果标题需要以下格式:

+---+---+---+----------+----------+----------+
|a  |b  |c  |aml_freq_a|aml_freq_b|aml_freq_c|
+---+---+---+----------+----------+----------+
然后

您可以使用DataFrameAPI以更简单、更安全的方式完成这项工作


我希望答案有帮助

你能编辑你的问题,向我们展示测试数据帧吗?@michailln,我已经编辑过,将其包括在内。使用数据帧连接,然后一个接一个地连接。测试数据帧中的每一行都有多个连接行,因此不可能创建这样的数据帧。此外,spark.sqlquery运行良好,因为它尚未运行。Spark是惰性计算的,这意味着只有当一个动作被触发时才会计算所有内容,如show See:@michailln yes,yes。我知道懒惰的评估。我总是在我所有的数据帧上调用show方法。这很有帮助。谢谢。我必须使用这里的sql,因为这部分进入函数,在有三个以上变量的情况下,使用sql提供了更大的灵活性。除了易于理解之外,使用DataFrameAPI还有其他好处吗?还有,你提到了更简单更安全的方法。你说这里更安全是什么意思?我指的是类型安全
query = "select test.* from " \
            "(select test.*, aml_freq_a from " \
                "(select test.*, aml_freq_b from " \
                    "(select test.*, aml_freq_c from test " \
                "left join train on test.c = train.c) as test " \
            "left join train on test.b = train.b)  as test " \
        "left join train on test.a = train.a) as test"
+---+---+---+----------+----------+----------+
|a  |b  |c  |aml_freq_a|aml_freq_b|aml_freq_c|
+---+---+---+----------+----------+----------+
query = "select test.* from " \
            "(select test.*, aml_freq_c from " \
                "(select test.*, aml_freq_b from " \
                    "(select test.*, aml_freq_a from test " \
                "left join train on test.a = train.a) as test " \
            "left join train on test.b = train.b)  as test " \
        "left join train on test.c = train.c) as test"
test.join(train.select('a', 'aml_freq_a'), ['a'], 'left') \
    .join(train.select('b', 'aml_freq_b'), ['b'], 'left') \
    .join(train.select('c', 'aml_freq_c'), ['c'], 'left')