![](/img/trans.png)
[英]Most computationally efficient way to map a unique number to each unique string in a column of lists
[英]How to map a unique number to each unique string in a column of lists
在pandas数据框中,我有一个列,其中每行包含一个字符串列表。 对于每个唯一的字符串,我想分配一个唯一的数字。
如果可能,我想为多列中的每个唯一字符串分配一个唯一的编号。
这是一个最小的例子:
设置初始pandas数据帧
df = pd.DataFrame(data={'A': ['2f4', '1k1', 'nmk'], 'B': ['x', 'y', 'z']})
df.at[0, 'B'] = ['jki', 'gg4', 'k6k']
df.at[1, 'B'] = ['2f4', 'gg4', 'g24']
df.at[2, 'B'] = ['1k1', 'g24', '1k1']
会是这样的
df
A B
0 2f4 [jki, gg4, k6k]
1 1k1 [2f4, gg4, g24]
2 nmk [1k1, g24, 1k1]
我正在寻找类似的结果
A B MappedA MappedB
0 2f4 [jki, gg4, k6k] 0 [3, 4, 5]
1 1k1 [2f4, gg4, g24] 1 [0, 4, 6]
2 nmk [1k1, g24, 1k1] 2 [1, 6, 1]
每个字符串都有一个唯一的编号,从0开始。如果再次出现一个字符串,则再次使用第一个分配的编号。
我找到了解决方案,其中列只有一个字符串或数字,如此
但我找不到任何列包含值列表的解决方案。
编辑:
澄清一下,b列中列表的长度是可变的。
pandas.factorize
和numpy.split
i, u = pd.factorize([*df.A, *np.concatenate(df.B)])
l = df.B.str.len()[:-1].cumsum()
n = len(df)
df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))
A B MappedA MappedB
0 2f4 [jki, gg4, k6k] 0 [3, 4, 5]
1 1k1 [2f4, gg4, g24] 1 [0, 4, 6]
2 nmk [1k1, g24, 1k1] 2 [1, 6, 1]
'A'
和'B'
分解在一起 'B'
中列表的长度,因为它们将帮助定义分割结果数组的位置 'MappedA'
n
假设我们有这个df
df = pd.DataFrame(data={'A': ['2f4', '1k1', 'nmk'], 'B': ['x', 'y', 'z']})
df.at[0, 'B'] = ['jki', 'gg4', 'k6k']
df.at[1, 'B'] = ['2f4', 'gg4', 'g24']
df.at[2, 'B'] = ['1k1', 'g24', '1k1', 'pir']
df
A B
0 2f4 [jki, gg4, k6k]
1 1k1 [2f4, gg4, g24]
2 nmk [1k1, g24, 1k1, pir]
然后相同的解决方案导致
i, u = pd.factorize([*df.A, *np.concatenate(df.B)])
l = df.B.str.len()[:-1].cumsum()
n = len(df)
df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))
A B MappedA MappedB
0 2f4 [jki, gg4, k6k] 0 [3, 4, 5]
1 1k1 [2f4, gg4, g24] 1 [0, 4, 6]
2 nmk [1k1, g24, 1k1, pir] 2 [1, 6, 1, 7]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.