繁体   English   中英

如何使用 python/pandas/numpy 将 pivot sql 表从行到列

[英]how to pivot a sql table from rows to columns with python/pandas/numpy

我有一个带有位掩码 ID 的字典表,如下所示:

来源数据

我想将它转换为这种结构:每一行的标签将成为一列,它的值将是组合(按位)。

示例:值 3 是1 和 2的组合,因此 a 将被赋予 1,b 将被赋予 1,并且列的所有 rest 均为 0

目标表

我已经使用带有按位运算符“&”的 SQL 服务器存储过程实现了它。 我想使用 python 来实现这个转换(我假设它会用 pandas 完成),因为每个标签都是 2 的 n 次方,所以我尝试使用从十进制到二进制的转换来解决它 - 这给我正是我所需要的,但我错过了如何将每一位附加到正确列示例 3 在二进制中表示为 11 的阶段,因此我想将 a 与 1 和 b 与 1 分配,所有 rest 应该为 0。

源表可能会添加额外的条目,因此 output 应该使用新行(例如 n,4096)更改目标表作为新列 m,根据值分配 1 或 0。

关于如何使用 python/pandas 解决这个问题有什么建议吗?

使用带移位 ( >> ) 的 numpy 广播将整数转换为由二进制填充的列,最后使用具有所有组合的新列DataFrame.dot以及列名和分隔符:

df = pd.DataFrame({'mask_id':range(1, 17)})

#list or Series of tags
L = list('abcdefghijklm')
#L = df2['Tags']

a = df.mask_id.to_numpy()
n = len(L)
data = (a[:, None] >> np.arange(n)) & 1

df1 = pd.DataFrame(data, index=df.index, columns=L)

df1['combinations'] = df1.dot(df1.columns + ',').str.rstrip(',')
print (df1)
    a  b  c  d  e  f  g  h  i  j  k  l  m combinations
0   1  0  0  0  0  0  0  0  0  0  0  0  0            a
1   0  1  0  0  0  0  0  0  0  0  0  0  0            b
2   1  1  0  0  0  0  0  0  0  0  0  0  0          a,b
3   0  0  1  0  0  0  0  0  0  0  0  0  0            c
4   1  0  1  0  0  0  0  0  0  0  0  0  0          a,c
5   0  1  1  0  0  0  0  0  0  0  0  0  0          b,c
6   1  1  1  0  0  0  0  0  0  0  0  0  0        a,b,c
7   0  0  0  1  0  0  0  0  0  0  0  0  0            d
8   1  0  0  1  0  0  0  0  0  0  0  0  0          a,d
9   0  1  0  1  0  0  0  0  0  0  0  0  0          b,d
10  1  1  0  1  0  0  0  0  0  0  0  0  0        a,b,d
11  0  0  1  1  0  0  0  0  0  0  0  0  0          c,d
12  1  0  1  1  0  0  0  0  0  0  0  0  0        a,c,d
13  0  1  1  1  0  0  0  0  0  0  0  0  0        b,c,d
14  1  1  1  1  0  0  0  0  0  0  0  0  0      a,b,c,d
15  0  0  0  0  1  0  0  0  0  0  0  0  0            e

如果列表中需要组合使用列表理解:

cols = df1.columns.to_numpy()
df1['combinations'] = [cols[x].tolist() for x in df1.to_numpy().astype(bool)]
print (df1)
    a  b  c  d  e  f  g  h  i  j  k  l  m  combinations
0   1  0  0  0  0  0  0  0  0  0  0  0  0           [a]
1   0  1  0  0  0  0  0  0  0  0  0  0  0           [b]
2   1  1  0  0  0  0  0  0  0  0  0  0  0        [a, b]
3   0  0  1  0  0  0  0  0  0  0  0  0  0           [c]
4   1  0  1  0  0  0  0  0  0  0  0  0  0        [a, c]
5   0  1  1  0  0  0  0  0  0  0  0  0  0        [b, c]
6   1  1  1  0  0  0  0  0  0  0  0  0  0     [a, b, c]
7   0  0  0  1  0  0  0  0  0  0  0  0  0           [d]
8   1  0  0  1  0  0  0  0  0  0  0  0  0        [a, d]
9   0  1  0  1  0  0  0  0  0  0  0  0  0        [b, d]
10  1  1  0  1  0  0  0  0  0  0  0  0  0     [a, b, d]
11  0  0  1  1  0  0  0  0  0  0  0  0  0        [c, d]
12  1  0  1  1  0  0  0  0  0  0  0  0  0     [a, c, d]
13  0  1  1  1  0  0  0  0  0  0  0  0  0     [b, c, d]
14  1  1  1  1  0  0  0  0  0  0  0  0  0  [a, b, c, d]
15  0  0  0  0  1  0  0  0  0  0  0  0  0           [e]

假设您需要二进制表示,这是一个不需要先前数据集的表示:

cols = ['a','b','c','d','e','f','g','h','i','j','k','l']
df = [list(('0'*(12-1)+"{0:b}".format(1))[::-1])]
for i in range(16):
    n = "{0:b}".format(i)
    df = df + [list(('0'*(12-len(n))+n)[::-1])]
df = pd.DataFrame(df, columns = cols)
df["combinations"] = df.apply(lambda x: list(x[x == '1'].index) ,axis = 1)

Output:

    a   b   c   d   e   f   g   h   i   j   k   l   combinations
0   1   0   0   0   0   0   0   0   0   0   0   0   [a]
1   0   0   0   0   0   0   0   0   0   0   0   0   []
2   1   0   0   0   0   0   0   0   0   0   0   0   [a]
3   0   1   0   0   0   0   0   0   0   0   0   0   [b]
4   1   1   0   0   0   0   0   0   0   0   0   0   [a, b]
5   0   0   1   0   0   0   0   0   0   0   0   0   [c]
6   1   0   1   0   0   0   0   0   0   0   0   0   [a, c]
7   0   1   1   0   0   0   0   0   0   0   0   0   [b, c]
8   1   1   1   0   0   0   0   0   0   0   0   0   [a, b, c]
9   0   0   0   1   0   0   0   0   0   0   0   0   [d]
10  1   0   0   1   0   0   0   0   0   0   0   0   [a, d]
11  0   1   0   1   0   0   0   0   0   0   0   0   [b, d]
12  1   1   0   1   0   0   0   0   0   0   0   0   [a, b, d]
13  0   0   1   1   0   0   0   0   0   0   0   0   [c, d]
14  1   0   1   1   0   0   0   0   0   0   0   0   [a, c, d]
15  0   1   1   1   0   0   0   0   0   0   0   0   [b, c, d]
16  1   1   1   1   0   0   0   0   0   0   0   0   [a, b, c, d]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM