简体   繁体   English

替换numpy数组的特定列中的值

[英]Replace values in specific columns of a numpy array

I have a N x M numpy array (matrix). 我有一个N x M的numpy数组(矩阵)。 Here is an example with a 3 x 5 array: 这是一个3 x 5数组的示例:

x = numpy.array([[0,1,2,3,4,5],[0,-1,2,3,-4,-5],[0,-1,-2,-3,4,5]])

I'd like to scan all the columns of x and replace the values of each column if they are equal to a specific value. 我想扫描x所有列,并替换每列的值(如果它们等于特定值)。 This code for example aims to replace all the negative values (where the value is equal to the column number) to 100: 例如,此代码旨在将所有负值(其中值等于列号)替换为100:

for i in range(1,6):
    x[:,i == -(i)] = 100 

This code obtains this warning: 此代码获得以下警告:

DeprecationWarning: using a boolean instead of an integer will result in an error in the future

I'm using numpy 1.8.2. 我正在使用numpy 1.8.2。 How can I avoid this warning without downgrade numpy? 如何在不降级numpy的情况下避免此警告?

I don't follow what your code is trying to do: 我不遵循您的代码试图做的事情:

the i == -(i) i == -(i)

will evaluate to something like this: 将评估为以下内容:

x[:, True]
x[:, False]

I don't think this is what you want. 我认为这不是您想要的。 You should try something like this: 您应该尝试这样的事情:

for i in range(1, 6):
    mask = x[:, i] == -i
    x[:, i][mask] = 100

Create a mask over the whole column, and use that to change the values. 在整个列上创建一个遮罩,并使用该遮罩更改值。

If you are worried about the warning spewing out text, then ignore it as a Warning/Exception: 如果您担心警告会喷出文本,请忽略它作为警告/异常:

import numpy
import warnings


warnings.simplefilter('default')  # this enables DeprecationWarnings to be thrown


x = numpy.array([[0,1,2,3,4,5],[0,-1,2,3,-4,-5],[0,-1,-2,-3,4,5]])

with warnings.catch_warnings():
    warnings.simplefilter("ignore")  # and this ignores them
    for i in range(1,6):
        x[:,i == -(i)] = 100
print(x)  # just to show that you are actually changing the content

As you can see in the comments, some people are not getting DeprecationWarning . 正如您在评论中看到的那样,有些人没有得到DeprecationWarning That is probably because python suppresses developer-only warnings since 2.7 这可能是因为python自2.7起就禁止开发人员警告

Even without the warning, the code you have there will not do what you want. 即使没有警告,那里的代码也不会做您想要的。 i is the loop index and will equal minus itself only if i == 0, which is never. i是循环索引,并且仅当i == 0时才等于负,否则永不等于。 Your test will always return false, which is cast to 0. In other words your code will replace the first element of each row with 100. 您的测试将始终返回false,并将其强制转换为0。换句话说,您的代码将每行的第一个元素替换为100。

To get this to work I would do 为了使这个工作我会做

for i in range(1, 6):
    col = x[:,i]
    col[col == -i] = 100

Notice that you use the name of the array for the masking and that you need to separate the conventional indexing from the masking 请注意,您使用数组的名称作为掩蔽,并且需要将常规索引与掩蔽分开

As others have said, your loop isn't doing what you think it is doing. 正如其他人所说的,您的循环并没有按照您认为的那样做。 I would propose you change your code to use numpy's fancy indexing. 我建议您更改代码以使用numpy的精美索引。

# First, create the "test values" (column index):
>>> test_values = numpy.arange(6)
# test_values is array([0, 1, 2, 3, 4, 5])
#
# Now, we want to check which columns have value == -test_values:
#
>>> mask = (x == -test_values) & (x < 0)
# mask is True wherever a value in the i-th column of x is negative i
>>> mask
array([[False, False, False, False, False, False],
       [False,  True, False, False,  True,  True],
       [False,  True,  True,  True, False, False]], dtype=bool)
#
# Now, set those values to 100
>>> x[mask] = 100
>>> x
array([[  0,   1,   2,   3,   4,   5],
       [  0, 100,   2,   3, 100, 100],
       [  0, 100, 100, 100,   4,   5]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM