用Numpy将数组划分为N个块

111 投票
7 回答
198228 浏览
提问于 2025-04-17 13:15

这里有一个关于如何将一个列表分成大小相等的块的讨论,链接在这里:如何将列表分成大小相等的块?。有人在问,是否有更高效的方法来处理非常大的数组,使用Numpy这个库。

7 个回答

10

这不是一个完整的答案,而是对其他(正确)答案的一个长评论,里面有很好的代码格式。如果你尝试下面的代码,你会发现你得到的是原始数组的视图,而不是它的副本。这和你提到的问题中被接受的答案是不一样的。要注意可能带来的副作用哦!

>>> x = np.arange(9.0)
>>> a,b,c = np.split(x, 3)
>>> a
array([ 0.,  1.,  2.])
>>> a[1] = 8
>>> a
array([ 0.,  8.,  2.])
>>> x
array([ 0.,  8.,  2.,  3.,  4.,  5.,  6.,  7.,  8.])
>>> def chunks(l, n):
...     """ Yield successive n-sized chunks from l.
...     """
...     for i in xrange(0, len(l), n):
...         yield l[i:i+n]
... 
>>> l = range(9)
>>> a,b,c = chunks(l, 3)
>>> a
[0, 1, 2]
>>> a[1] = 8
>>> a
[0, 8, 2]
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8]
28

这里有一些关于如何使用 array_splitsplithsplitvsplit 的例子:

n [9]: a = np.random.randint(0,10,[4,4])

In [10]: a
Out[10]: 
array([[2, 2, 7, 1],
       [5, 0, 3, 1],
       [2, 9, 8, 8],
       [5, 7, 7, 6]])

使用 array_split 的一些例子:
如果你把一个数组或列表作为第二个参数传入,实际上就是告诉程序在哪些位置“切割”这个数组。

# split rows into 0|1 2|3
In [4]: np.array_split(a, [1,3])
Out[4]:                                                                                                                       
[array([[2, 2, 7, 1]]),                                                                                                       
 array([[5, 0, 3, 1],                                                                                                         
       [2, 9, 8, 8]]),                                                                                                        
 array([[5, 7, 7, 6]])]

# split columns into 0| 1 2 3
In [5]: np.array_split(a, [1], axis=1)                                                                                           
Out[5]:                                                                                                                       
[array([[2],                                                                                                                  
       [5],                                                                                                                   
       [2],                                                                                                                   
       [5]]),                                                                                                                 
 array([[2, 7, 1],                                                                                                            
       [0, 3, 1],
       [9, 8, 8],
       [7, 7, 6]])]

如果第二个参数是一个整数,那就表示你想把数组分成相等的几块:

In [6]: np.array_split(a, 2, axis=1)
Out[6]: 
[array([[2, 2],
       [5, 0],
       [2, 9],
       [5, 7]]),
 array([[7, 1],
       [3, 1],
       [8, 8],
       [7, 6]])]

split 的工作方式和 array_split 类似,但如果无法均匀分割,它会报错。

除了 array_split,你还可以使用快捷方式 vsplithsplit
vsplithsplit 的意思很简单:

In [11]: np.vsplit(a, 2)
Out[11]: 
[array([[2, 2, 7, 1],
       [5, 0, 3, 1]]),
 array([[2, 9, 8, 8],
       [5, 7, 7, 6]])]

In [12]: np.hsplit(a, 2)
Out[12]: 
[array([[2, 2],
       [5, 0],
       [2, 9],
       [5, 7]]),
 array([[7, 1],
       [3, 1],
       [8, 8],
       [7, 6]])]
159

可以试试 numpy.array_split

根据文档的说明:

>>> x = np.arange(8.0)
>>> np.array_split(x, 3)
    [array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.]), array([ 6.,  7.])]

这个功能和 numpy.split 是一样的,但如果分组的长度不一样,它不会报错。

如果你想分成的块数比数组的长度还多,你会得到一些空的数组嵌套在里面。要解决这个问题,如果你把分好的数组保存到 a 里,你可以通过以下方式去掉空数组:

[x for x in a if x.size > 0]

如果你愿意,可以把结果再保存回 a

撰写回答