将字符串列表转换为 Python 中的类别整数
Convert a list of string to category integer in Python
给定一个字符串列表,
['a', 'a', 'c', 'a', 'a', 'a', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'b', 'b', 'b', 'd', 'b', 'b', 'b']
我想转换成整数类别形式
[0, 0, 2, 0, 0, 0, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 1, 1, 1, 3, 1, 1, 1]
这可以使用 numpy unique 实现,如下所示
ipt=['a', 'a', 'c', 'a', 'a', 'a', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'b', 'b', 'b', 'd', 'b', 'b', 'b']
_, opt = np.unique(np.array(ipt), return_inverse=True)
但是,我很好奇是否有另一种不需要导入的替代方法 numpy
。
你可以从函数式编程书上做个笔记:
ipt=['a', 'a', 'c', 'a', 'a', 'a', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'b', 'b', 'b', 'd', 'b', 'b', 'b']
opt = list(map(lambda x: ord(x)-97, ipt))
此代码遍历输入数组并将每个元素传递给 lambda 函数,该函数采用字符的 ascii 值,然后减去 97(将字符转换为 0-25)。
如果每个字符串不是单个字符,则可能需要调整 lambda 函数。
如果您只对查找因子的整数表示感兴趣,那么在使用 set
查找唯一值后,您可以使用字典理解和 enumerate
来存储映射:
lst = ['a', 'a', 'c', 'a', 'a', 'a', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'b', 'b', 'b', 'd', 'b', 'b', 'b']
d = {x: i for i, x in enumerate(set(lst))}
lst_new = [d[x] for x in lst]
print(lst_new)
# [3, 3, 0, 3, 3, 3, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 1, 1, 1, 2, 1, 1, 1]
这种方法可以用于一般因素,即因素不一定是'a'
、'b'
等,但可以是'dog'
、'bus'
, 等。一个缺点是它不关心因素的顺序。如果您希望表示保留顺序,可以使用 sorted
:
d = {x: i for i, x in enumerate(sorted(set(lst)))}
lst_new = [d[x] for x in lst]
print(lst_new)
# [0, 0, 2, 0, 0, 0, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 1, 1, 1, 3, 1, 1, 1]
您可以编写一个自定义函数来执行与您使用 numpy.unique()
相同的操作。
def unique(my_list):
''' Takes a list and returns two lists, a list of each unique entry and the index of
each unique entry in the original list
'''
unique_list = []
int_cat = []
for item in my_list:
if item not in unique_list:
unique_list.append(item)
int_cat.append(unique_list.index(item))
return unique_list, int_cat
或者,如果您希望对索引进行排序。
def unique_ordered(my_list):
''' Takes a list and returns two lists, an ordered list of each unique entry and the
index of each unique entry in the original list
'''
# Unique list
unique_list = []
for item in my_list:
if item not in unique_list:
unique_list.append(item)
# Sorting unique list alphabetically
unique_list.sort()
# Integer category list
int_cat = []
for item in my_list:
int_cat.append(unique_list.index(item))
return unique_list, int_cat
将这两个的计算时间与 numpy.unique()
的示例列表的 100,000 次迭代进行比较,我们得到:
numpy = 2.236004s
unique = 0.460719s
unique_ordered = 0.505591s
显示对于简单列表,任一选项都比 numpty 更快。更复杂的字符串使 unique()
和 unique_ordered
的速度下降比 numpy.unique()
大得多。对包含 20 个字符串的 100 个元素的随机列表进行 10,000 次迭代,我们得到以下时间:
numpy = 0.45465s
unique = 1.56963s
unique_ordered = 1.59445s
因此,如果效率很重要并且您的列表中有更多 complex/a 种类繁多的字符串,那么使用 numpy.unique()
可能会更好
给定一个字符串列表,
['a', 'a', 'c', 'a', 'a', 'a', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'b', 'b', 'b', 'd', 'b', 'b', 'b']
我想转换成整数类别形式
[0, 0, 2, 0, 0, 0, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 1, 1, 1, 3, 1, 1, 1]
这可以使用 numpy unique 实现,如下所示
ipt=['a', 'a', 'c', 'a', 'a', 'a', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'b', 'b', 'b', 'd', 'b', 'b', 'b']
_, opt = np.unique(np.array(ipt), return_inverse=True)
但是,我很好奇是否有另一种不需要导入的替代方法 numpy
。
你可以从函数式编程书上做个笔记:
ipt=['a', 'a', 'c', 'a', 'a', 'a', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'b', 'b', 'b', 'd', 'b', 'b', 'b']
opt = list(map(lambda x: ord(x)-97, ipt))
此代码遍历输入数组并将每个元素传递给 lambda 函数,该函数采用字符的 ascii 值,然后减去 97(将字符转换为 0-25)。
如果每个字符串不是单个字符,则可能需要调整 lambda 函数。
如果您只对查找因子的整数表示感兴趣,那么在使用 set
查找唯一值后,您可以使用字典理解和 enumerate
来存储映射:
lst = ['a', 'a', 'c', 'a', 'a', 'a', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'd', 'd', 'd', 'd', 'c', 'b', 'b', 'b', 'd', 'b', 'b', 'b']
d = {x: i for i, x in enumerate(set(lst))}
lst_new = [d[x] for x in lst]
print(lst_new)
# [3, 3, 0, 3, 3, 3, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 1, 1, 1, 2, 1, 1, 1]
这种方法可以用于一般因素,即因素不一定是'a'
、'b'
等,但可以是'dog'
、'bus'
, 等。一个缺点是它不关心因素的顺序。如果您希望表示保留顺序,可以使用 sorted
:
d = {x: i for i, x in enumerate(sorted(set(lst)))}
lst_new = [d[x] for x in lst]
print(lst_new)
# [0, 0, 2, 0, 0, 0, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 1, 1, 1, 3, 1, 1, 1]
您可以编写一个自定义函数来执行与您使用 numpy.unique()
相同的操作。
def unique(my_list):
''' Takes a list and returns two lists, a list of each unique entry and the index of
each unique entry in the original list
'''
unique_list = []
int_cat = []
for item in my_list:
if item not in unique_list:
unique_list.append(item)
int_cat.append(unique_list.index(item))
return unique_list, int_cat
或者,如果您希望对索引进行排序。
def unique_ordered(my_list):
''' Takes a list and returns two lists, an ordered list of each unique entry and the
index of each unique entry in the original list
'''
# Unique list
unique_list = []
for item in my_list:
if item not in unique_list:
unique_list.append(item)
# Sorting unique list alphabetically
unique_list.sort()
# Integer category list
int_cat = []
for item in my_list:
int_cat.append(unique_list.index(item))
return unique_list, int_cat
将这两个的计算时间与 numpy.unique()
的示例列表的 100,000 次迭代进行比较,我们得到:
numpy = 2.236004s
unique = 0.460719s
unique_ordered = 0.505591s
显示对于简单列表,任一选项都比 numpty 更快。更复杂的字符串使 unique()
和 unique_ordered
的速度下降比 numpy.unique()
大得多。对包含 20 个字符串的 100 个元素的随机列表进行 10,000 次迭代,我们得到以下时间:
numpy = 0.45465s
unique = 1.56963s
unique_ordered = 1.59445s
因此,如果效率很重要并且您的列表中有更多 complex/a 种类繁多的字符串,那么使用 numpy.unique()