提问人:Leo 提问时间:1/9/2022 更新时间:1/9/2022 访问量:963
将 2 列中的唯一值映射到整数
Map unique values in 2 columns to integers
问:
我有一个带有 2 个分类列(col1、col2)的数据帧。
col1 col2
0 A DE
1 A B
2 B BA
3 A A
4 C C
我想将唯一的字符串值映射到整数,例如(A:0、B:1、BA:2、C:3、DE:4)
col1 col2 ideal1 ideal2
0 A DE 0 4
1 A B 0 1
2 B BA 1 2
3 A A 0 0
4 C C 3 3
我尝试使用因式分解或类别,但我没有得到两列相同的唯一值,从 ROW C 中可以看出:
这是我的代码:
df = pd.DataFrame({'col1': ["A", "A", "B", "A" , "C"], 'col2': ["DE", "B", "BA", "A", "C"]})
#ideal map alphabetical: A:0, B:1, BA:2, C:3, DE:4
#ideal result
df["ideal1"] = [0, 0, 1,0, 3]
df["ideal2"] = [4,1,2,0,3]
#trial #1 --> C value 2 & 3 : not matching
df["cat1"] = df['col1'].astype("category").cat.codes
df["cat2"] = df['col2'].astype("category").cat.codes
#trial #2 --> C value 2 & 4 : not matching
df["fac1"] = pd.factorize(df["col1"])[0]
df["fac2"] = pd.factorize(df["col2"])[0]
print (df)
OUT:
col1 col2 ideal1 ideal2 cat1 cat2 fac1 fac2
0 A DE 0 4 0 4 0 0
1 A B 0 1 0 1 0 1
2 B BA 1 2 1 2 1 2
3 A A 0 0 0 0 0 3
4 C C 3 3 2 3 2 4
答:
5赞
mozway
1/9/2022
#1
要跨列获取相同的类别,您需要先调整为单个维度。然后使用并恢复原始形状。factorize
下面是一个使用 / 的示例:stack
unstack
x = df.stack()
x[:] = x.factorize()[0]
df2 = x.unstack()
输出:
col1 col2
0 0 1
1 0 2
2 2 3
3 0 0
4 4 4
联接到原始数据:
x = df.stack()
x[:] = x.factorize()[0]
df2 = df.join(x.unstack().add_suffix('_cat'))
输出:
col1 col2 col1_cat col2_cat
0 A DE 0 1
1 A B 0 2
2 B BA 2 3
3 A A 0 0
4 C C 4 4
按字母顺序排列
如果你真的想要按字母顺序排列,你可以创建你自己的自定义映射字典:
import numpy as np
cats = {k:v for v,k in enumerate(np.unique(df.values))}
df.replace(cats)
输出:
col1 col2
0 0 4
1 0 1
2 1 2
3 0 0
4 3 3
评论
0赞
Leo
1/9/2022
谢谢,即使使用更大的数据集,这也非常快!
1赞
mozway
1/9/2022
@Leo我添加了字母顺序的更新,但可能会更慢;)
0赞
sammywemmy
1/9/2022
为那里的错误编辑道歉
0赞
mozway
1/9/2022
@sammywemmy字典理解是有意为之的,那么需要将其反转键和值;)不用担心,您的编辑通常是不错的改进!
2赞
Nick ODell
1/9/2022
#2
如果您对哪些代码映射到哪些整数有偏好,我建议使用 map,它接受指定映射方式的字典。
例:
import pandas as pd
df = pd.DataFrame({'col1': ["A", "A", "B", "A" , "C"], 'col2': ["DE", "B", "BA", "A", "C"]})
mapping_dict = {'A':0, 'B':1, 'BA':2, 'C':3, 'DE':4}
df['ideal1'] = df['col1'].map(mapping_dict)
df['ideal2'] = df['col2'].map(mapping_dict)
print(df)
输出:
col1 col2 ideal1 ideal2
0 A DE 0 4
1 A B 0 1
2 B BA 1 2
3 A A 0 0
4 C C 3 3
@mozway 解决方案的优点是无需指定映射。
评论
0赞
Leo
1/9/2022
谢谢,在我原来的问题中,我有大约 200 个类别,所以不会从字典中映射,但非常有用的答案。
评论