实际问题:数据能按日期来过滤,但是分到每天的数据不均匀,这样的情况下要按时间段分片取数据。每次取出的数据总量又受内存限制。
问题:将一个有序数组切分成若干个子组,每个子组中的数求和都不超过100。
def split_numlist(numlist, hold=100):
some_num = 0 # 子组数值和
nums = [] # 子组
sub_numlist = [] # 子组切分结果
for n in numlist:
some_num += n
if some_num >= hold:
if len(nums) > 0:
sub_numlist.append(nums)
nums = [n]
some_num = n
else:
nums.append(n)
if len(nums) > 0:
sub_numlist.append(nums)
print(*sub_numlist, sep='\n')
print(*[sum(numlist) for numlist in sub_numlist], sep=' ')
>>> numlist = [1, 6, 4, 4, 1, 7, 8, 7, 7, 6, 12, 14, 25, 1, 49, 29, 1, 20, 52, 40, 36, 50, 45, 39, 9, 32, 32, 27, 25, 17]
>>> split_numlist(numlist)
[1, 6, 4, 4, 1, 7, 8, 7, 7, 6, 12, 14]
[25, 1, 49]
[29, 1, 20]
[52, 40]
[36, 50]
[45, 39, 9]
[32, 32, 27]
[25, 17]
77 75 50 92 86 93 91 42
结果分成8组,每组数和不大于100。
如果这个数组中的数值不代表数字,而是代表数据规模,要对这30个分区的数据进行分组计算,每个组能容纳的规模在100以下,且分好的各个子组相互独立(可并行操作)。
分好的各子组规模需要尽可能相近,保证每个进程的完成时间差距较小。
可以设置一个小于100的上限重新分:
all_count = sum(numlist)
slice_count = all_count // 100 + 1
hold = round(all_count/slice_count)
得到的上限是87,使用这个值重新分组:
>>> split_numlist(numlist, hold=87)
[1, 6, 4, 4, 1, 7, 8, 7, 7, 6, 12, 14]
[25, 1, 49]
[29, 1, 20]
[52]
[40, 36]
[50]
[45, 39]
[9, 32, 32]
[27, 25, 17]
77 75 50 52 76 50 84 73 69
分成9个组,各组和的差距相较上一次有所减小。