【发布时间】:2015-05-05 18:01:43
【问题描述】:
已编辑:我的代码如下所示:
__author__ = 'feynman'
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
def MC_Surface(volume, mc_vol):
Perm_area = {
"00000000": 0.000000,
"11111111": 0.000000,
...
...
"11100010": 1.515500,
"00011101": 1.515500
}
cdef int j, i, k
for k in range(volume.shape[2] - 1):
for j in range(volume.shape[1] - 1):
for i in range(volume.shape[0] - 1):
pattern = '%i%i%i%i%i%i%i%i' % (
volume[i, j, k],
volume[i, j + 1, k],
volume[i + 1, j, k],
volume[i + 1, j + 1, k],
volume[i, j, k + 1],
volume[i, j + 1, k + 1],
volume[i + 1, j, k + 1],
volume[i + 1, j + 1, k + 1])
mc_vol[i, j, k] = Perm_area[pattern]
return mc_vol
为了提速,修改为:
{
...
...
"11100010": 1.515500,
"00011101": 1.515500
}
keys = np.array(Perm_area.keys())
values = np.array(Perm_area.values())
starttime = time.time()
tmp_vol = GetPattern(volume)
print 'time to populate the key array: ', time.time() - starttime
cdef int i
starttime=time.time()
for i, this_key in enumerate(keys):
mc_vol[tmp_vol == this_key] = values[i]
print 'time for the loop: ', time.time() -starttime
return mc_vol
def GetPattern(volume):
a = (volume.astype(np.int)).astype(np.str)
output = a.copy() # Central voxel
output[:, :-1, :] = np.char.add(output[:, :-1, :], a[:, 1:, :]) # East
output[:-1, :, :] = np.char.add(output[:-1, :, :], a[1:, :, :]) # South
output[:-1, :-1, :] = np.char.add(output[:-1, :-1, :], a[1:, 1:, :]) # SouthEast
output[:, :, :-1] = np.char.add(output[:, :, :-1], a[:, :, 1:]) # Down
output[:, :-1, :-1] = np.char.add(output[:, :-1, :-1], a[:, 1:, 1:]) # DownEast
output[:-1, :, :-1] = np.char.add(output[:-1, :, :-1], a[1:, :, 1:]) # DownSouth
output[:-1, :-1, :-1] = np.char.add(output[:-1, :-1, :-1], a[1:, 1:, 1:]) # DownSouthEast
output = output[:-1, :-1, :-1]
del a
return output
对于大小为 500^3 的 3D 数组,这需要更长的时间。这里是 tmp_vol 3D 字符串数组。例如:如果说 tmp_vol[0,0,0] = "00000000" 那么 mc_vol[0,0,0] = 0.00000。或者,我可以去掉 mc_vol 并写 if tmp_vol[0,0,0] = "00000000" then tmp_vol[0,0,0] = 0.00000。
这里,for循环需要很多时间,我看到只使用了一个CPU。我尝试使用 map 和 lambda 并行映射它们,但遇到了错误。我对 python 很陌生,所以任何提示都会很棒。
【问题讨论】:
-
能否更好地解释您的代码实际上做了什么?什么是 tmp_vol?
-
感谢您的回复! tmp_vol 具有字典 Perm_area = { "00000000": 0.000000, ... ... ... "11100010": 1.515500, "00011101": 1.515500 } 中的键。在 tmp_vol 填充了键之后,键将被字典 Perm_area 中的相应值替换为它们在 3D 数组中的相应位置。例如:如果说 tmp_vol[0,0,0] = "00000000" 那么 mc_vol[0,0,0] = 0.00000。或者,如果 tmp_vol[0,0,0] = "00000000" 那么 tmp_vol[0,0,0] = 0.00000 也可以。
标签: python multithreading loops parallel-processing mapping