首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将表转换为多行的一次热编码

将表转换为多行的一次热编码
EN

Stack Overflow用户
提问于 2019-05-09 19:53:55
回答 2查看 2.6K关注 0票数 4

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

代码语言:javascript
复制
ID  Cat
1   A   
1   B
1   D
1   F
2   B
2   C
2   D
3   A
3   F

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

代码语言:javascript
复制
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多个猫,所以我正在寻找代码来自动编写,而不是手动编写。谁能帮我解决这个问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-10 06:39:14

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

代码语言:javascript
复制
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编码:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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编码:

代码语言:javascript
复制
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,但您需要使用该结果编写一个新的查询。

票数 4
EN

Stack Overflow用户

发布于 2019-05-10 05:01:18

对于standardSQL,BigQuery没有动态列,但是根据您在下一步要做的事情,可能有一种方法可以让它更简单。

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

代码语言:javascript
复制
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;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56058860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档