【问题标题】:Transform table to one-hot encoding for many rows将表转换为多行的 one-hot 编码
【发布时间】:2019-09-27 06:09:54
【问题描述】:

我有一个如下格式的 SQL 表:

ID  Cat
1   A   
1   B
1   D
1   F
2   B
2   C
2   D
3   A
3   F

现在,我想创建一个表,每行有一个 ID,并且一行中有多个 Cat。我想要的输出如下所示:

ID  A  B  C  D  E  F
1   1  1  0  1  0  1
2   0  1  1  1  0  0
3   1  0  0  0  0  1

我找到了:

Transform table to one-hot-encoding of single column value

但是,我有 1000 多只猫,所以我正在寻找代码来自动编写,而不是手动编写。谁能帮我解决这个问题?

【问题讨论】:

标签: sql google-bigquery one-hot-encoding


【解决方案1】:

首先让我将您粘贴的数据转换为实际表格:

WITH data AS (
  SELECT REGEXP_EXTRACT(data2, '[0-9]') id, REGEXP_EXTRACT(data2, '[A-Z]') cat
  FROM (
    SELECT SPLIT("""1   A   
    1   B
    1   D
    1   F
    2   B
    2   C
    2   D
    3   A
    3   F""", '\n') AS data1
  ), UNNEST(data1) data2
)

SELECT * FROM data

(下次尝试共享一张桌子)

现在我们可以进行一些手动 1-hot 编码:

SELECT id 
 , MAX(IF(cat='A',1,0)) cat_A
 , MAX(IF(cat='B',1,0)) cat_B
 , MAX(IF(cat='C',1,0)) cat_C
FROM data
GROUP BY id

现在我们要编写一个脚本来自动创建我们想要的列:

SELECT STRING_AGG(FORMAT("MAX(IF(cat='%s',1,0))cat_%s", cat, cat), ', ') 
FROM (
  SELECT DISTINCT cat
  FROM data
  ORDER BY 1
)

生成一个字符串,您可以将其复制粘贴到查询中,1-hot 对您的数组/行进行编码:

SELECT id
,
MAX(IF(cat='A',1,0))cat_A, MAX(IF(cat='B',1,0))cat_B, MAX(IF(cat='C',1,0))cat_C, MAX(IF(cat='D',1,0))cat_D, MAX(IF(cat='F',1,0))cat_F
FROM data
GROUP BY id

这正是问题所要求的。您可以使用 SQL 生成 SQL,但您需要使用该结果编写新查询。

【讨论】:

  • 嗯,对我来说不是很有效...我得到“查询太大。最大标准 SQL 查询长度为 1024.00K 个字符,包括 cmets 和空白字符。”...我猜我将不得不结合查询或其他东西。这越来越傻了。 Python是:P
【解决方案2】:

BigQuery 没有使用标准 SQL 的动态列,但根据您在下一步中要执行的操作,可能有一种方法可以使其变得更容易。

以下代码示例按 ID 对 Cat 进行分组,并使用 JavaScript 函数进行 one-hot 编码并返回 JSON 字符串。

CREATE TEMP FUNCTION trans(cats ARRAY<STRING>)
RETURNS STRING
LANGUAGE js
AS
"""
// TODO: Doing one hot encoding for one cat and return as JSON string
return "{a:1}";
"""
;
WITH id_cat AS (
SELECT 1 as ID, 'A' As Cat UNION ALL
SELECT 1 as ID, 'B' As Cat UNION ALL
SELECT 1 as ID, 'C' As Cat UNION ALL
SELECT 2 as ID, 'A' As Cat UNION ALL
SELECT 3 as ID, 'C' As Cat)
SELECT ID, trans(ARRAY_AGG(Cat))
FROM id_cat
GROUP BY ID;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-26
    • 2023-03-13
    • 2022-01-22
    • 1970-01-01
    • 2017-07-27
    • 2021-08-19
    • 2022-01-19
    相关资源
    最近更新 更多