2015-02-08 46 views
3

我有一个问题,我有元组称为状态和行为,我想计算它的“二进制功能”。下面描述计算状态和动作特征的功能。请注意,这只是一个玩具代码。我有大约700,000个状态和动作组合。我还需要具有numpy数组/ 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 

回答

2

如果以尽可能快的速度返回结果非常关键,那么应该考虑选项一。但是,您应该记住内存和安装时间开销,这可能太昂贵了。

如果表现完全不是问题,那么您应该更喜欢选项二。这将使您的代码更简单,不会不必要地增加内存消耗和设置时间。

如果性能确实发挥了一定的作用,但并不一定要尽可能每次都可能,我建议将这两个选项结合起来。 要享受这两个世界,您可以使用Memoization。基本上,它意味着你按需求计算结果,但在返回它们之前,你把它们放在字典中,就像你所建议的那样。该函数将尝试在字典中查找结果,并仅在必要时计算结果。 Here是一个很好的教程,用于在python中实现memoization。

+0

Python 3.2+仅为此目的而具有[@ functools.lru_cache](https://docs.python.org/3.4/library/functools.html#functools.lru_cache)装饰器。 – wwii 2015-02-08 18:28:25

+0

有趣。我会看看这个。 – 2015-02-09 02:51:40

+0

我选择了第一个选项,性能几乎提高了400%。 – 2015-02-09 15:31:06

相关问题