Создайте все возможные комбинации между двумя столбцами и индикатором, чтобы показать, существует ли эта комбинация в исходной таблице. - PullRequest
0 голосов
/ 25 апреля 2018

Я совершенно потерян на определенном этапе выполнения трансформации.

Я планирую достичь этого с помощью SQL или pyspark.

Мой формат ввода:

id  name
1   A
1   C
1   E
2   A
2   B
2   C
2   E
2   F
3   A
3   E
3   D

Не могли бы вы помочь мне получить этот выходной формат.

id name rating
1  A    1
1  B    0
1  C    1
1  D    0
1  E    1
1  F    0
2  A    1
2  B    1
2  C    1
2  D    0
2  E    1
2  F    1
3  A    1
3  B    0
3  C    0
3  D    1
3  E    1
3  F    0

Поскольку запрос sql выполняется вечно, я просто хочу посмотреть, смогу ли я добиться того же, используя pyspark для подачи набора данных в ALS.

Другими словами, как мне сгенерировать все возможные комбинации между идентификатором и именем, и если комбинация существует в таблице, установить рейтинг в 1, иначе 0?

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

Я сделал функцию, основанную на ответе Рэймонда Нейландса:

def expand_grid(df, df_name, col_a, col_b, col_c):
    df.createOrReplaceTempView(df_name)
    expand_sql = f"""
        SELECT
            expanded.{col_a},
            expanded.{col_b},
            CASE
                WHEN {df_name}.{col_c} IS NULL THEN 0
                ELSE {df_name}.{col_c}
            END AS {col_c}
        FROM ( 
            SELECT *
            FROM (
                SELECT DISTINCT {col_a}
                FROM {df_name}    
            ) AS {col_a}s
            CROSS JOIN (
                SELECT DISTINCT {col_b}
                FROM {df_name}
            ) AS {col_b}s
        ) AS expanded
        LEFT JOIN {df_name}
        ON expanded.{col_a} = {df_name}.{col_a}
        AND expanded.{col_b} = {df_name}.{col_b}
    """
    print(expand_sql)
    result = spark.sql(expand_sql)
    return result

Использование в контексте этого вопроса:

expand_grid(df=df, df_name="df_name", col_a="id", col_b="name", col_c="rating")
0 голосов
/ 25 апреля 2018

Другими словами генерировать все возможные комбинации между id и имя .. если комбинация существует с в таблице, рейтинг равен 1 в противном случае 0?

Вам нужно использовать две таблицы производных в сочетании с CROSS JOIN, чтобы получить все возможные комбинации идентификаторов и имен.

Запрос

SELECT 
 *
FROM ( 

 SELECT 
   *
  FROM (
    SELECT
      DISTINCT
       id
    FROM
      Table1    
  ) AS distinct_id
  CROSS JOIN (
    SELECT 
      DISTINCT 
        name
    FROM 
    Table1 
  ) AS distinct_name
) AS table_combination

 ORDER BY 
    id ASC
  , name ASC

Результат

| id | name |
|----|------|
|  1 |    A |
|  1 |    B |
|  1 |    C |
|  1 |    D |
|  1 |    E |
|  1 |    F |
|  2 |    A |
|  2 |    B |
|  2 |    C |
|  2 |    D |
|  2 |    E |
|  2 |    F |
|  3 |    A |
|  3 |    B |
|  3 |    C |
|  3 |    D |
|  3 |    E |
|  3 |    F |

см. Демонстрацию http://sqlfiddle.com/#!9/ba5f17/17

Теперь мы можем использовать LEFT JOIN в сочетании с CASE WHEN column IS NULL ... END, чтобы проверить, существует ли комбинация в текущей таблице или генерируется комбинация.

Запрос

SELECT
   Table_combination.id
 , Table_combination.name
 , (
     CASE 
      WHEN Table1.id IS NULL
      THEN 0
      ELSE 1
     END
   ) AS rating
FROM ( 

  SELECT 
   *
  FROM (
    SELECT
      DISTINCT
       id
    FROM
      Table1    
  ) AS distinct_id
  CROSS JOIN (
    SELECT 
      DISTINCT 
        name
    FROM 
    Table1 
  ) AS distinct_name
) AS Table_combination

LEFT JOIN 
 Table1
ON
   Table_combination.id = Table1.id
 AND
   Table_combination.name = Table1.name

ORDER BY 
   Table_combination.id ASC
 , Table_combination.name ASC

Результат

| id | name | rating |
|----|------|--------|
|  1 |    A |      1 |
|  1 |    B |      0 |
|  1 |    C |      1 |
|  1 |    D |      0 |
|  1 |    E |      1 |
|  1 |    F |      0 |
|  2 |    A |      1 |
|  2 |    B |      1 |
|  2 |    C |      1 |
|  2 |    D |      0 |
|  2 |    E |      1 |
|  2 |    F |      1 |
|  3 |    A |      1 |
|  3 |    B |      0 |
|  3 |    C |      0 |
|  3 |    D |      1 |
|  3 |    E |      1 |
|  3 |    F |      0 |

см. Демонстрацию http://sqlfiddle.com/#!9/ba5f17/13

...