每次迭代后如何减小ndarray的大小?

时间:2018-07-15 01:32:44

标签: python-3.x numpy

我有一个ndarray A:

A =[  1
      3
      5
      2
      4
   ]

我想做的是:

在第一次迭代中选择A的最大值,并将其存储在另一个列表B中,并在存储后删除该元素。再次从A中剩余的项目中选择最大值,然后将其存储在B中,依此类推,直到A变空为止。

我有以下代码:

B = []
for I in range(len(A)):
    temp = []
    p = A.max()
    temp.append(p)
    A.remove(A[i])
    B.append(temp)

我收到以下错误:

error: A.remove(A[i])
ndarray has no attribute remove()

2 个答案:

答案 0 :(得分:2)

首先列出该代码的列表版本(有效):

In [36]: A = [1,3,5,2,4]
In [37]: B = []
In [38]: for i in range(5):
    ...:     p = max(A)
    ...:     B.append(p)
    ...:     A.remove(p)
    ...:     
In [39]: A
Out[39]: []
In [40]: B
Out[40]: [5, 4, 3, 2, 1]

等效数组(不推荐):

In [41]: A = [1,3,5,2,4]
In [42]: A = np.array(A)
In [43]: B = []
In [44]: for i in range(5):
    ...:     j = np.argmax(A)
    ...:     B.append(A[j])
    ...:     A = np.delete(A,j)
    ...:     
In [45]: A
Out[45]: array([], dtype=int64)
In [46]: B
Out[46]: [5, 4, 3, 2, 1]

np.delete.remove不同。它通过索引而不是值来工作。因此,我必须使用argmax来找到最大值而不是最大值本身的索引。 delete无法就地工作。这是一个复杂的函数,它返回一个新数组(很可能是通过将A[:j]A[j+1:]连接起来)

In [50]: for i in range(5):
    ...:     j = np.argmax(A)
    ...:     B.append(A[j])
    ...:     A = np.concatenate((A[:j],A[j+1:]))

答案 1 :(得分:1)

NumPy数组的大小固定。它们不可调整大小,这意味着要真正“删除”一个元素需要将所有其他元素复制到一个新数组中,这效率非常低,并且一开始就无法使用NumPy。

请考虑代码的实际作用:它会生成一个排序列表。这样可以更快,更少的代码完成相同的事情:

np.sort(A)[::-1].tolist()