代码之家  ›  专栏  ›  技术社区  ›  Clock Slave

pyspark sql:用作表达式的子查询返回了多行:

  •  0
  • Clock Slave  · 技术社区  · 7 年前

    我试图在我的 test 使用另一个名为 train . 下面是快照。在 火车 数据帧,列下第一行中的值 aml_freq_a 是次数 v 出现在列中 a . 同样地, 42 在下面 aml_freq_b 是次数 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_freq_a'、'aml_freq_b'、'aml_freq_c'] .

    >>> test.show(5)
    +---+---+---+
    |  a|  b|  c|
    +---+---+---+
    |  w|  j|  c|
    |  a|  g|  w|
    |  s|  d|  i|
    |  g|  j|  r|
    |  r|  b|  u|
    +---+---+---+
    

    为此,我编写了连接 火车 测试 a,b 而且, c .

    query = "select test.*,
      (select aml_freq_a from test left join train on test.a = train.a),
      (select aml_freq_b from test left join train on test.b = train.b),
      (select aml_freq_c from ten left join train on test.c = train.c)
    from test"
    
    train.createTempView('train')
    test.createTempView('test')
    

    spark.sql(query) 运行良好,但当我打电话时 show() 它返回以下错误

    java.lang.RuntimeException: more than one row returned by a subquery used as an expression:
    

    这是什么意思?起初我以为我的查询有问题,但我验证了我的查询。 here 这里没什么问题。我在这里没有看到什么?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Ramesh Maharjan    7 年前

    在你的尝试中, (select aml_freq_a from test left join train on test.a = train.a) 会返回一个 dataframe 多行 不能用作select参数作为 "select test.*, (select aml_freq_a from test left join train on test.a = train.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|
    +---+---+---+----------+----------+----------+
    

    然后

    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"
    

    你可以用更简单更安全的方法 使用数据帧API

    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')
    

    我希望答案有帮助

        2
  •  0
  •   user9822761    7 年前

    这意味着

    • 您使用的至少一个相关子查询返回多个匹配项。
    • 虽然spark只支持为每行返回一个值(即相关子查询必须聚合)。