格式化多维数组 Python

Formatting Multi dimensional arrays Python

如何编写代码,在出现负值后立即将多维数组 a 中每个单独数组的值更改为零。因此 a 中的第二个数组的负值 [12,34,5,6,88,-10,30,75] 为 -10,它将把它的所有值和紧随其后的值变为零。将数组变成 [12,34,5,6,88,0,0,0]。我怎样才能得到我的预期输出?

import numpy as np 

a = np.array([[12,45,50,60,30],
             [12,34,5,6,88,-10,30,75],
             [3,45,332,45,-12,-4,-64,12],
             [12,45,3,22,323]])

预期输出:

[[12,45,50,60,30],
 [12,34,5,6,88,0,0,0],
 [3,45,332,45,0,0,0,0],
 [12,45,3,22,323]]

试试这个:

import numpy as np 

a = np.array([[12,45,50,60,30],
             [12,34,5,6,88,-10,30,75],
             [3,45,332,45,-12,-4,-64,12],
             [12,45,3,22,323]], dtype='object')


for l in a:
    for i in l:
        if i<0:
            l[l.index(i):] = [0] * len(l[l.index(i):])
            
a

输出:

array([list([12, 45, 50, 60, 30]), list([12, 34, 5, 6, 88, 0, 0, 0]),
       list([3, 45, 332, 45, 0, 0, 0, 0]), list([12, 45, 3, 22, 323])],
      dtype=object)

第二个解决方案:

import numpy as np 

def neg_to_zero(l):
    for i in l:
        if i<0:
            l[l.index(i):] = [0] * len(l[l.index(i):])

a = np.array([[12,45,50,60,30],
             [12,34,5,6,88,-10,30,75],
             [3,45,332,45,-12,-4,-64,12],
             [12,45,3,22,323]], dtype='object')

list(map(neg_to_zero, a))

a

你的数组:

In [608]: a = np.array([[12,45,50,60,30],
     ...:              [12,34,5,6,88,-10,30,75],
     ...:              [3,45,332,45,-12,-4,-64,12],
     ...:              [12,45,3,22,323]])
<ipython-input-608-894f7005e102>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  a = np.array([[12,45,50,60,30],
In [609]: a
Out[609]: 
array([list([12, 45, 50, 60, 30]), list([12, 34, 5, 6, 88, -10, 30, 75]),
       list([3, 45, 332, 45, -12, -4, -64, 12]),
       list([12, 45, 3, 22, 323])], dtype=object)

这包含长度不同的列表。它不是多维的。使它成为一个数组,而不是将其保留为列表的列表,并不会使其更容易处理。

无论哪种方式,您都必须迭代,并分别更改每个列表。

首先关注。如果您的数据不合适,请不要使用 numpy。您的数据不适合 numpy,因为您有一个列表列表,其中每个包含的列表具有 不同的 长度。如果所有 相同 长度(矩阵形状),它将适用于 numpy。

针对问题本身:将其简化为解决单个列表上的任务,然后转换每个列表。

data = [
    [12, 45, 50, 60, 30],
    [12, 34, 5, 6, 88, -10, 30, 75],
    [3, 45, 332, 45, -12, -4, -64, 12],
    [12, 45, 3, 22, 323]
]
for row in data:
    transform(row)

算法:我们将遍历列表,当我们找到负元素时,我们知道当前位置,然后我们可以设置后面的所有元素。

我将向您展示两种变体。

第一个变体使用切片。它还使用 enumerate(),它为列表(或其他可迭代对象)提供 (index, value) 个元组。

def transform(lst):
    for (index, value) in enumerate(lst):
        if value < 0:
            lst[index:] = [0] * (len(lst) - index)

它通过将 [0](1 元素列表)乘以余数的长度来创建一个用零填充的新列表。然后它将其分配给正在转换的列表的一部分。此切片分配会更改列表本身。

第二个变体使用一些“状态”:

def transform(lst):
    do_overwrite = False
    for (index, value) in enumerate(lst):
        if value < 0:
            do_overwrite = True # "flips a switch", stay on
        if do_overwrite:
            lst[index] = 0

Python 列表是对象,就像 python 中的几乎所有其他内容一样。这意味着,当您调用一个函数并将列表作为参数传递时,该列表不会被复制,但函数调用会获取该列表对象以供使用。对该对象的任何更改...对调用者都是“可见的”,因为它是处理的同一个列表对象。