[英]Split of numpy array into unequal chunks
在我的程序中,我用元素填充了一個大型的numpy
數組,這些元素的數量我事先並不知道。 由於每次向numpy
數組添加單個元素效率低下,因此我將其大小增加了用零初始化的長度為10000的塊。 這導致最終我有一個尾巴為零的數組。 我想要的是數組,數組的長度恰好是有意義的元素的數量(因為稍后我無法將零零與零值的實際數據點區分開)。 但是,直接復制切片會使RAM消耗增加一倍,這確實是不希望的,因為我的數組很大。 我研究了numpy.split
函數,但是它們似乎只能將數組拆分為大小相等的塊,這當然不適合我。
我用以下代碼說明了這個問題:
import numpy, os, random
def check_memory(mode_peak = True, mark = ''):
"""Function for measuring the memory consumption (Linux only)"""
pid = os.getpid()
with open('/proc/{}/status'.format(pid), 'r') as ifile:
for line in ifile:
if line.startswith('VmPeak' if mode_peak else 'VmSize'):
memory = line[: -1].split(':')[1].strip().split()[0]
memory = int(memory) / (1024 * 1024)
break
mode_str = 'Peak' if mode_peak else 'Current'
print('{}{} RAM consumption: {:.3f} GB'.format(mark, mode_str, memory))
def generate_element():
"""Test element generator"""
for i in range(12345678):
yield numpy.array(random.randrange(0, 1000), dtype = 'i4')
check_memory(mode_peak = False, mark = '#1 ')
a = numpy.zeros(10000, dtype = 'i4')
i = 0
for element in generate_element():
if i == len(a):
a = numpy.concatenate((a, numpy.zeros(10000, dtype = 'i4')))
a[i] = element
i += 1
check_memory(mode_peak = False, mark = '#2 ')
a = a[: i]
check_memory(mode_peak = False, mark = '#3 ')
check_memory(mode_peak = True, mark = '#4 ')
輸出:
#1 Current RAM consumption: 0.070 GB
#2 Current RAM consumption: 0.118 GB
#3 Current RAM consumption: 0.118 GB
#4 Peak RAM consumption: 0.164 GB
誰能幫助我找到不會嚴重影響運行時間或RAM消耗的解決方案?
編輯:
我嘗試使用
a = numpy.delete(a, numpy.s_[i: ])
以及
a = numpy.split(a, (i, ))[0]
但是,它導致內存消耗翻倍
numpy.split不必將數組拆分為相等大小的塊。 如果使用indices_or_sections
參數,則可以給出一個整數列表,它將用於分割數組。 例如:
>>> x = np.arange(8.0)
>>> np.split(x, [3, 5, 6, 10])
[array([ 0., 1., 2.]), # x[:3]
array([ 3., 4.]), # x[3:5]
array([ 5.]), # x[5:6]
array([ 6., 7.]), # x[6:10]
array([], dtype=float64)] # x[10:]
終於我明白了。 實際上,不僅在修剪階段,而且在串聯過程中都消耗了額外的內存。 因此,在點#2
輸出處引入峰值內存檢查:
#2 Peak RAM consumption: 0.164 GB
但是,有一個resize()
方法,可以就地更改數組的大小/形狀:
check_memory(mode_peak = False, mark = '#1 ')
page_size = 10000
a = numpy.zeros(page_size, dtype = 'i4')
i = 0
for element in generate_element():
if (i != 0) and (i % page_size == 0):
a.resize(i + page_size)
a[i] = element
i += 1
a.resize(i)
check_memory(mode_peak = False, mark = '#2 ')
check_memory(mode_peak = True, mark = '#2 ')
這導致輸出:
#1 Current RAM consumption: 0.070 GB
#2 Current RAM consumption: 0.118 GB
#2 Peak RAM consumption: 0.118 GB
此外,由於沒有更多的重新分配,因此性能也得到了顯着改善。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.