我有一个包含 N 个数组的数据集,每个数组可能有固定或可变长度。我将从数据集中提取一个窗口并计算给定数字的出现次数。为简单起见,我假设每个数组包含 90 个数字。模型会在每个数组上随机选取一个位置,从该位置开始提取M个连续的数字作为窗口条,这样就得到了总共N条。我假设每个条带具有相同的大小,因此所有 N 个条带构成一个视图(窗口)。我有一个 C++ 代码来执行这项工作并且工作得很好,对于 5x90 的数据集,重复窗口采样 1000000 次,每 10,000 次迭代完成大约需要 0.002 秒。我正在尝试将 C++ 移植到 Python,以便我可以使用强大的数据框 (Pandas) 和其他工具进行相关分析。经过一些研究,似乎 Numpy 数组是数据数组的一个很好的表示,但由于每个数组的大小各不相同,我需要将所有数组扭曲成一个列表。我在下面显示的代码(删除了大部分不相关的代码)
import numpy as np
import random
import time
class dataSource:
_data = None
_NCOLS = 0
_NROWS = 0
# NCOLS, NROWS is the dimension of a window (view) of the data
# _data is a list of NCOLS Numpy array, each array carry 90 numbers
def __init__(self, NCOLS, NROWS):
# assuming each array has 90 numbers for this exmaple, it could be varied in actual case
src = [[1]*90]*NCOLS # just assume all numbers in the array to be 1 for this example
self._data = [np.array(cc) for cc in src]
self._NCOLS = NCOLS
self._NROWS = NROWS
def extractView(self, view):
pos = [random.randint(0, len(cc)-1-self._NROWS) for cc in self._data]
for col in range(len(self._data)):
view[:, col] = self._data[col][pos[col]:pos[col]+self._NROWS]
class dataView:
_NCOLS = 0
_NROWS = 0
_view = None
def __init__(self, NCOLS, NROWS):
self._NCOLS = NCOLS
self._NROWS = NROWS
self._view = np.zeros([self._NROWS, self._NCOLS], order='F')
def __setitem__(self, key, value):
self._view[key] = value
def count(self, elem):
return np.count_nonzero(self._view==elem)
if __name__ == '__main__':
ds = dataSource(5, 3)
dv = dataView(5, 3)
batchCount, totalTime, startTime = 1, 0, time.process_time()
for n in range(10000000):
if ((n+1)%10000==0):
dt = time.process_time() - startTime
totalTime += dt
print(totalTime / batchCount, ' ', dt)
batchCount += 1
startTime = time.process_time()
ds.extractView(dv)
cnt = dv.count(1) # this could then be used for other analysis, dv may be used by other functions
在 Python 3.8.8 中运行此代码显示代码每 10,000 次迭代需要 0.23 秒才能完成。 Python 代码比 C++ 慢大约 100 倍。在实际情况下,数据源最多可以有 50 个数组,每个数组可能有 50 到 500 个数字,因此 Python 中的运行时间可能会更长。在真实数据中应用C++代码,完成所有迭代大约需要5个小时,根据上面的估算,在Python中做同样的工作需要500个小时。我知道 Python 中可能存在一些限制,因此很难提高速度,但是如果我能做任何事情来优化我的代码以减少时间(甚至 10%)都会有很大帮助。