Sql 将表转换为单列值的一个热编码

Sql 将表转换为单列值的一个热编码,sql,postgresql,crosstab,Sql,Postgresql,Crosstab,我有一个包含两列的表: +---------+--------+ | keyword | color | +---------+--------+ | foo | red | | bar | yellow | | fobar | red | | baz | blue | | bazbaz | green | +---------+--------+ 我需要在PostgreSQL中对表进行某种热编码和转换,以便: +---------+-----

我有一个包含两列的表:

+---------+--------+
| keyword | color  |
+---------+--------+
| foo     | red    |
| bar     | yellow |
| fobar   | red    |
| baz     | blue   |
| bazbaz  | green  |
+---------+--------+
我需要在PostgreSQL中对表进行某种热编码和转换,以便:

+---------+-----+--------+-------+------+
| keyword | red | yellow | green | blue |
+---------+-----+--------+-------+------+
| foo     |   1 |      0 |     0 |    0 |
| bar     |   0 |      1 |     0 |    0 |
| fobar   |   1 |      0 |     0 |    0 |
| baz     |   0 |      0 |     0 |    1 |
| bazbaz  |   0 |      0 |     1 |    0 |
+---------+-----+--------+-------+------+

是否可以只使用SQL?关于如何开始的任何提示?

如果我理解正确,您需要条件聚合:

select keyword,
count(case when color = 'red' then 1 end) as red,
count(case when color = 'yellow' then 1 end) as yellow
-- another colors here
from t
group by keyword

要在具有大量列的表上使用此代码,请使用Python生成查询:

1) 创建一个包含唯一变量的列表,您希望将其作为列名,并将其导入Python,例如:
list

for item in list:
 print('count(case when item=' +str(item)+ 'then 1 end) as is_'+str(item)+',')
2) 复制输出(减去最后一行的最后一个逗号)

3) 然后:


在您的测试用例中使用扩展和

如果您只是想在
psql
下获得结果:

postgres=# select keyword, color, COALESCE('1',0) as onehot from t
  --group by 1, 2 order by 1, 2
  \crosstabview keyword color
 keyword | red | yellow | blue | green 
---------+-----+--------+------+-------
 foo     |   1 |        |      |      
 bar     |     |      1 |      |      
 fobar   |   1 |        |      |      
 baz     |     |        |    1 |      
 bazbaz  |     |        |      |     1
(5 rows)

postgres=# 

one hot encoding
的意思是什么?您的“颜色”列表是预先知道的吗?@PM77-1是的,仅这四种。@Siyual这是转换的名称,即将分类数据转换为数字,其中每个类别都在单独的列中。然后对每个“颜色”使用
大小写。如果
关键字
颜色
对不是唯一的,则需要添加聚合。不确定它为什么被否决,它正好完成了任务。现在看起来很明显,谢谢。这确实符合原始问题的标准,但我正在寻找一种方法,为数据科学家动态地对100+列进行热编码。它基本上需要透视每个列的潜在值,并动态地进行操作。希望有人已经写出了动态SQL@njkroes,你找到答案了吗?我遇到了类似的情况,我希望编码的列列表可能会change@njfrazie我最终只是使用了一堆IIF语句来完成这项工作。在查找大量数据的情况下,您可以获取所有表示的答案并动态生成某些内容,但除非您已经知道需要做什么,否则实际上无法动态地为一条记录执行某些操作。在这种情况下,你只需写出所有的预期结果,就像这个答案所建议的那样。
postgres=# create table t(keyword varchar,color varchar);
CREATE TABLE
postgres=# insert into t values ('foo','red'),('bar','yellow'),('fobar','red'),('baz','blue'),('bazbaz','green');
INSERT 0 5
postgres=# SELECT keyword, COALESCE(red,0) red, 
 COALESCE(blue,0) blue, COALESCE(green,0) green, 
 COALESCE(yellow,0) yellow 
 FROM crosstab(                         
  $$select keyword, color, COALESCE('1',0) as onehot from test01
    group by 1, 2 order by 1, 2$$,
  $$select distinct color from test01 order by 1$$)
 AS result(keyword varchar, blue int, green int, red int, yellow int);
 keyword | red | blue | green | yellow 
---------+-----+------+-------+--------
 bar     |   0 |    0 |     0 |      1
 baz     |   0 |    1 |     0 |      0
 bazbaz  |   0 |    0 |     1 |      0
 fobar   |   1 |    0 |     0 |      0
 foo     |   1 |    0 |     0 |      0
(5 rows)

postgres=# 
postgres=# select keyword, color, COALESCE('1',0) as onehot from t
  --group by 1, 2 order by 1, 2
  \crosstabview keyword color
 keyword | red | yellow | blue | green 
---------+-----+--------+------+-------
 foo     |   1 |        |      |      
 bar     |     |      1 |      |      
 fobar   |   1 |        |      |      
 baz     |     |        |    1 |      
 bazbaz  |     |        |      |     1
(5 rows)

postgres=#