Python 将值过多的行转换为列

Python 将值过多的行转换为列,python,mysql,sql,Python,Mysql,Sql,假设我有一个这样的数据集 ID Item 1 A 2 B 3 A 1 C 2 B 2 B 1 A 3 B 实际数据集有50K行和8.5K个不同的项值 现在我想将每个Id的行转换为列,这样我们就可以为每个用户计算每个项的值。如下 ID A B C 1 2 0 1 2 0 3 0 3 1 1 0 现在,若我有相同数量的项值,那个么我可以在case-aggregate语句中对它们进行硬编码 差不多 select ID,

假设我有一个这样的数据集

ID  Item
1   A
2   B
3   A
1   C
2   B
2   B
1   A
3   B
实际数据集有50K行和8.5K个不同的项值

现在我想将每个Id的行转换为列,这样我们就可以为每个用户计算每个项的值。如下

ID  A   B   C
1   2   0   1
2   0   3   0
3   1   1   0
现在,若我有相同数量的项值,那个么我可以在case-aggregate语句中对它们进行硬编码

差不多

select ID, count(case when Item ='A' then 1 else Null end) A, 
count(case when Item='B' then 1 else Null end) B... and so on. 
但在这种情况下,我有8.5公里独特的项目。在sql中,上述任务太多,无法完成

Sql和ii)Python是如何实现这一点的。请记住,我有50K行和8.5k个唯一项,因此python循环可能会有点慢

但我的第一个目标是在sql中实现这一点,因为这是一个50K的示例数据。当数据变得更大时,sql仍然能够很好地保存数据,但我觉得python的速度会变慢。在python中,我也可以尝试一些代码。但同样,当数据超过50K obs时,python的速度也会变慢

请告知


不使用Postgresql和HANA,因此特定于Postgres的函数可能无法工作。请建议通用sql方式

如果您确实想在python中执行此操作,您应该查看
pandas

df = pd.DataFrame({
    'ID': [1, 2, 3, 1, 2, 2, 1, 3],
    'Item': ['A', 'B', 'A', 'C', 'B', 'B' , 'A', 'B']
})

pd.crosstab(df['ID'], df['Item'])
输出:

Item A  B   C
ID          
1   2   0   1
2   0   3   0
3   1   1   0

对于SQL解决方案,使用SQL技术但编写脚本怎么样?不知道它能撑多久,但如果你还没有试过的话,你可以试一试。 运行类似这样的操作以生成所需所有列的脚本:

select distinct 'sum(case when ITEM = ''' + ITEM + ''' then 1 else 0 end) ' + ITEM + ',' from YOUR_TABLE;
然后复制并粘贴结果以得出:

select 
  ID,
  **<COPY AND PASTE RESULTS HERE>**
from TEST_DATA
group by ID;
选择
身份证件
****
从测试数据
按ID分组;

此查询可以生成所需的查询:

SELECT CONCAT("SELECT ID"
    , GROUP_CONCAT(DISTINCT 
        CONCAT(", COUNT(CASE Item WHEN '", Item, "' THEN 1 ELSE NULL END) AS `", Item, "`")
        ORDER BY Item
        )
    , "FROM `theTable` "
    , "GROUP BY ID"
  ) AS theQuery
FROM `theTable`
;
…但我只知道在MySQL中肯定存在
GROUP_CONCAT
,而在MSSQL中不存在;我不知道其他数据库系统。此外,在MySQL中,您需要通过在该查询前面加上如下语句来增加函数允许的最大长度

SET SESSION group_concat_max_len = 1000000;
…或更改服务器配置以增大默认最大值。 …其中“1000000”是一个足够大的长度,不会截断结果字符串

如果查询太大,无论采用何种设置,group_concat都无法适应:您可以运行多个查询,使用Where来减少处理的
值,以生成较小的“、计数(…)、计数(“列表”;然后手动合并这些结果


当然,即使这生成了所需的查询,我也不确定MySQL是否会接受这么长的查询。

您要找的是一个MySQL不支持的“交叉表”查询。它必须是代码(或存储过程),或类似于您提议的查询。但该查询应使用
SUM
,或计数中的ELSE应为
ELSE NULL
;计数为0。正确。但我不能使用我提议的一个。我在项中有8.5K个唯一值。不能硬编码8.5K次。那么它的8k行代码。我使用的是HANA,而不是Mysql。我正在寻找一个基因ric sql查询在任何特定函数(如Pivot或Crosstab)之外,因为Pivot和Crosstab在HANA中不存在。您是否需要在某个位置显示该信息(导出)或者你需要访问应用程序中的计数才能进行计算?基本上,我正在处理一个数据集,如上图1所示。我需要将其转换为2,以便我可以使用2进行进一步的分析。数据必须是2格式才能进行分析。这就是w为什么我需要创建一个新的数据集来从1转换为2。为什么不呢?谢谢。但我担心的是,当行和值超过50K和8.5K时,数据集的速度可能会变慢。所以sql在那里会更好。关于如何在sql中实现这一点,有什么想法吗?我尝试过它不起作用。但是我现在正在尝试用Python对其进行原型化。为此,我从HA中提取数据NA到python。我使用了以下代码。它在拉取时会给我一些空值。HANA中的原始表没有任何空值。不确定为什么会这样?sql=“”从“表A”中选择*df=psql.read_sql(sql,conn)恐怕我对HANA不熟悉。你用什么连接?如果你做一些类似于
cur=conn.cursor();cur.execute('SELECT*FROM“Table A””);cur.fetchmany(5)
的事情,你会得到什么?你把sum语句放在引号内。我删除了引号并尝试了。错误。SAP DBTech JDBC:[257]:sql语法错误:“+ITEM+”附近的语法不正确:第1行第74列(在第74位)尝试以下操作:
select distinct concat('sum(当ITEM='',ITEM,'',然后是1 else 0 end'),ITEM,'')从您的_表中;
记住,这是生成供您使用的脚本,而不是实际执行它。这就是sum语句包含引号的原因。您必须手动将结果复制并粘贴到第二条语句中(同时删除最后一个逗号)。这只是为了让您不必为8.5k个不同的项目键入案例。不起作用。SAP DBTech JDBC:[316]:函数调用中的参数数量错误:第1行第17列(位置16)不确定问题出在哪里。请参阅此处的演示: