使用 numpy array_split() 获得所需的不是子倍数的分割大小

Using numpy array_split() to get desired split-size that is not a sub-multiple

我有一个字节数组,大小为 268238。(dtype="uint8") 我如何将它们分成每个大小为 2211 的子数组? 余数数组可以更小。

总的来说:出于某种原因,我尝试使用 numpy 将文件拆分为大小为 2211 字节的块。 (附加信息:之后我想 base64_encode 数组中的所有这些 2211 个元素,但这仅供您参考)

# create an array to test the problem
import numpy as np
a = np.random.randint(255, size=268238).astype("uint8")
# check size and dtype.
a.size
a.dtype
# until now everything is fine
# now i want to split it in equal parts of 2211 elements
# last one may be smaller
# 
https://docs.scipy.org/doc/numpy/reference/generated/numpy.array_split.html
# just take the elements size now... 
(np.array_split(a, a.size // 2211))[0].size # <-- 2217... but why?
(np.array_split(a, a.size // 2211))[1].size # <-- 2217... but why?
# ...
(np.array_split(a, a.size // 2211))[120].size # <-- 2216 (remainder..)

numpy.array_split方法是否有错误?

我预计每个块都是 2211 个元素(uint8 的 2211 个数字)。相反,我得到了 2217 个元素的块大小。 使用 119、120、121 或 122 作为 array_split 的参数并不重要。我仍然没有得到 2211 的块大小。

提前感谢您的帮助:)

** 编辑:** 这是做的工作,但需要回答的问题, 为什么 array_split 的行为与预期不符。有人可以解释一下吗?

out = [a[i : i + 2211] for i in range(0, len(a), 2211)]
out[121].size
#  707 <-- the correct remainder

array_split() 上的 numpy documentation 表示,不是将每个片段的大小传递给 array_split() 函数,您还可以选择将索引传递到您想要拆分的位置发生。 使用这个想法,下面的代码会给你你正在寻找的结果:

import numpy as np
a = np.random.randint(255, size=268238).astype("uint8")
split_positions = list(range(2211,268238,2211))
split_result = np.array_split(a, split_positions)
frag_size_list = [p.size for p in split_result]
print (frag_size_list)

这个输出是:

[2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 707]

您的代码无法运行的原因与所涉及的算法有关。如果您尝试使用片段大小重新计算原始大小,您就会意识到这一点。

进一步详细说明为什么您的代码不起作用:

268238 /  2211 = 121.3198
268238 // 2211 = 121

您正在将 121 作为片段数传递给 array_split() 函数。但这会产生您正在寻找的 2211 的碎片大小吗?下面的算术表明它不会:

268238 / 121 = 2216.843(大约 2217)。