我有一组大约5到100行、5000到25000列的大型数据集(二维矩阵)。我被告知从每一行中提取一条,给出了条的长度。对于每一行,将从该行的随机位置开始填充条带,并一直填充,如果该位置超出该行的长度,它将从开始拾取条目,就像周期边界一样。例如,假设一行有10个元素
row = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
该位置拾取为8,条带长度为4。然后,条带将被[9, 10, 1, 2]
首先,我尝试使用NumPy进行计算
A = np.ones((5, 8000), order='F')
import time
L = (4,3,3,3,4) # length for each of the 5 strips
starttime = time.process_time()
for i in range(80000):
B = []
for c, row in enumerate(A):
start = random.randint(0,len(row)-1)
end = start+L[c]
if end>len(row)-1:
sce = np.zeros(L[c])
for k in range(start, end):
sce[k-start] = k%len(row)
else:
sce = row[start:end]
B = sce
print(time.process_time() - starttime)
我没有处理边界条件的好方法,所以我把它分成两种情况:一种是当整个条带在行内,另一种是当条带的一部分在行外。此代码有效,运行大约需要1.5秒。然后我试着用列表代替
A = [[1]*8000]*5
starttime = time.process_time()
for i in range(80000):
B = []
for c, row in enumerate(A):
start = random.randint(0,len(row)-1)
end = start+L[c]
if end>len(row)-1:
sce = np.zeros(L[c])
for k in range(start, end):
sce[k-start] = k%len(row)
else:
sce = row[start:end]
B = sce
print(time.process_time() - starttime)
这一个大约快了0.5秒,我很惊讶我期望NumPy会更快!!!这两种代码都适用于较小的矩阵大小和较少的迭代次数。但在实际项目中,我将处理一个非常大的矩阵和更多的迭代,我想知道是否有任何建议来提高效率。此外,对于如何处理周期性边界条件(更整洁、更高效),是否有任何建议
考虑到在计时之前创建数组
A
,这两种解决方案的速度相同,因为您只是在数组上迭代。但我实际上不知道为什么纯python解决方案更快,也许是因为基于集合的迭代器(枚举)更适合原始python类型查看一行的示例,您希望从该行中获取一系列元素,并环绕越界索引。为此,我建议:
输出:
然后,可以通过指定
axis
关键字将此行为扩展到两个维度。但是在L
中处理长度不均匀的数组确实有点棘手,因为使用非均匀数组会失去使用numpy的大部分好处。解决方法是以相同大小的长度分组在一起的方式对L
进行分区如果我正确理解了整个任务,那么会给您一些起始值,并且希望沿
A
的第二个轴提取每个对应的条带长度输出:
尽管如此,看起来您希望每行都有一个随机的起始位置
相关问题 更多 >
编程相关推荐