这很难解释,但我有一个元组列表,其中每个元组的长度为 n,每个元组中项目的可能值都包含在一组列表中(元组中的每个位置都有一个列表)。
举个简单的例子,我的元组列表可能是
sequence = [('b', 1), ('c', 2), ('c', 1), ('a', 3), ('c', 2), ('a', 3)]
可能值的列表是:
state_lists = [['a', 'b', 'c'], [1, 2, 3, 4]]
我想要一种类似于 sequence
的有效方法来创建列表或数组(首选整数数组),但每个值都由 state_lists
中相应列表中的索引替换.
这是一种利用 np.searchsorted 的解决方案。不幸的是,这个函数只支持一维数组:
import numpy as np
sequence_as_array = np.array(sequence)
sequence_indexes = [
np.searchsorted(states, sequence_as_array[:, i])
for i, states in enumerate(state_lists)
]
lookup_array = np.vstack(sequence_indexes).T
print(lookup_array)
[[1 0]
[2 1]
[2 0]
[0 2]
[2 1]
[0 2]]
有没有更简单的方法来做到这一点(例如,不使用 for 循环,将 sequence
转换为数组并避免 vstack
)?
它一定是一个通用的解决方案,因为元组的长度可能大于2,并且数据类型可以是float、int或string。
替换值的原因是为了创建一个查找数组以实现快速索引,并且比存储原始值占用更少的内存。 序列
的长度可能超过10,000。
最佳答案
实现此目的的一种有效方法是使用 pandas 中对分类序列的内置支持:
import pandas as pd
sequence = [('b', 1), ('c', 2), ('c', 1), ('a', 3), ('c', 2), ('a', 3)]
df = pd.DataFrame(sequence, dtype='category')
print(df[0].cat.categories.to_numpy())
# ['a', 'b', 'c']
print(df[0].cat.codes.to_numpy())
# [1 2 2 0 2 0]
Pandas 对于此类事情具有相当优化的代码路径,您可以在您的用例中利用它们,而无需自己重新实现它们。
关于python - 当元组中每个位置的值来自不同的列表时,从元组序列创建值索引数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65785455/