我有一个问题,我有一个名为状态和动作的元组,我想计算它的"二进制功能"。计算状态和动作特征的功能如下所述。请注意,这只是一个玩具代码。
我有大约700,000个州和行动的组合。我还需要在numpy array / scipy稀疏矩阵中使用这些特性。
现在,问题是,我必须计算状态和行动的特征数百万次。我想到了两个选择。
一种选择是预先使用所有700,000种组合下面的函数进行计算,并将其存储在字典中。键是(状态,动作),值是二进制特征。
另一个选择是每次我想要找到每个状态和动作的二进制特征的值时调用下面的函数。
我的目标是获得良好的性能并且还能提高内存效率。
from numpy import array
from scipy import sparse
def compute_features(state, action):
# state and action are 3-tuples of integers.
# e.g. (1, 2, 3)
return array(state) - array(action)
def computer_binary_features(state, action, coord_size):
# e.g.
# features = (1, 0, 2)
# sizes = (2, 2, 3)
# Meaning, the size of first coordinate is 2, second is 2 and third is 3.
# It means the first coordinate can only take value integers 0 to 7.
#
# What this function does is turning (1, 0, 2) into binary features.
# For the first coordinate, the value is 1 and the size is 2, so the binary
# features of the first coordinate it (0, 1).
# Second coordinate, the value is 0 and the size is 2. The binary features
# is (1, 0)
# Third coordinate, the value is 2 and the size is 3. The binary features is
# (0, 0, 1).
#
# So the binary features of (1, 0, 2) is: (0, 1, 1, 0, 0, 0, 1)
#
# This function does not do concatenation but rather finding position of ones
# in the binary features of size sum(sizes).
# returns a coo sparse 0-1 valued 1 x n matrix.
features = compute_features(state, action)
coord_size = array(coord_size)
col = []
index = 0
for i in range(len(features)):
index = index + coord_size[i]
col.append(index + features[i] - min_elem[i])
row = [0] * len(col)
data = [1] * len(col)
mtx = sparse.coo_matrix((data, (row, col)), (1, sum(coord_size)),
dtype=np.uint8)
return mtx
答案 0 :(得分:2)
如果尽可能快地返回结果非常关键,那么您应该考虑选项一。但是,您应该记住内存和设置时间开销,这可能太昂贵了。
如果性能根本不是问题,您应该更喜欢选项二。这将使您的代码更简单,并且不会不必要地增加内存消耗和设置时间。
如果性能确实发挥了一定的作用,但不一定非常好,我建议将这两个选项结合起来。 要享受这两个世界,您可以使用Memoization。基本上,它意味着您可以按需计算结果,但在返回之前,您可以按照建议将它们放入字典中。该函数将尝试在字典中查找结果,并仅在必要时计算结果。 Here是在python中实现memoization的一个很好的教程。