PySpark SQL: более одной строки, возвращаемой подзапросом, используемым в качестве выражения: - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь создать новый столбец в моем test фрейме данных, используя значения из другого фрейма данных с именем train.Ниже приведен снимок.В кадре данных 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|
+---+---+---+----------+----------+----------+

В наборе данных test есть столбцы ['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|
+---+---+---+

Для этого я написал подзапросы, которые объединяют train и test в 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:

Что это значит?Сначала я думал, что с моим запросом что-то не так, но я проверил свой запрос здесь , и здесь нет ничего плохого.Что я здесь не вижу?

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

В вашей попытке (select aml_freq_a from test left join train on test.a = train.a) вернет dataframe, то есть несколько строк , которые нельзя использовать в качестве аргумента выбора, так как "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"

Вы можете сделать это намного более простым и безопасным способом используя dataframe 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')

Надеюсь, ответ будет полезным

0 голосов
/ 21 мая 2018

Это означает, что

  • Как минимум один из используемых вами коррелированных подзапросов возвращает более одного совпадения.
  • Хотя Spark поддерживает только одно значение, возвращаемое для каждой строки (т.е. коррелированные подзапросы)должны быть агрегированы).
...