将np.where中未包含的元素设置为np.nan

时间:2022-03-04 21:24:44

How can I set all the elements that are not 7 as np.nan?

如何将所有不是7的元素设置为np.nan?

import numpy as np
data  = np.array([[0,1,2,3,4,7,6,7,8,9,10], 
        [3,3,3,4,7,7,7,8,11,12,11],  
        [3,3,3,5,7,7,7,9,11,11,11],
        [3,4,3,6,7,7,7,10,11,11,11],
        [4,5,6,7,7,9,10,11,11,11,11]])

result = np.where(data==7) 
data[~result] = np.nan
print data

Traceback (most recent call last):
  File "M:\test.py", line 10, in <module>
    data[~result] = np.nan
TypeError: bad operand type for unary ~: 'tuple'

3 个解决方案

#1


2  

There must be a better way but this is the best I can think of right now. Make another array of all np.nan, and then replace the values at the indices in result with the real values:

必须有一个更好的方法,但这是我现在能想到的最好的方法。创建所有np.nan的另一个数组,然后将结果中的索引处的值替换为实际值:

data_nan = np.full(data.shape, np.nan)
data_nan[result] = data[result]
data = data_nan

If you want to get a list of all indices that are not in result, you could do this, though I think the above is probably better:

如果你想得到一个没有结果的所有索引的列表,你可以这样做,虽然我认为上面可能更好:

inc = np.core.rec.fromarrays(result)
all_ind = np.core.rec.fromarrays(np.indices(data.shape).reshape(2,-1))
exc = np.setdiff1d(all_ind, inc)
data[exc['f0'], exc['f1']] = np.nan

This works by turning each pair of indices into one element of a structured array, so that they can be compared as set elements to a similar array of all indices. Then we do the set difference of these and get the rest.

这通过将每对索引转换为结构化数组的一个元素来工作,因此可以将它们作为集合元素与所有索引的类似数组进行比较。然后我们做这些的设定差异,并得到其余的。

#2


3  

Use the 3-argument form of np.where:

使用np.where的3参数形式:

In [49]: np.where(data==7, data, np.nan)
Out[49]: 
array([[ nan,  nan,  nan,  nan,  nan,   7.,  nan,   7.,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,   7.,   7.,  nan,  nan,  nan,  nan,  nan,  nan]])

or

要么

In [62]: np.choose(data==7, [np.nan, data])
Out[62]: 
array([[ nan,  nan,  nan,  nan,  nan,   7.,  nan,   7.,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,   7.,   7.,  nan,  nan,  nan,  nan,  nan,  nan]])

Regarding the requirement that the integer indices returned by using_filters be used in this solution, I think there is a better alternative. If you were to remove the np.where from using_filters:

关于在此解决方案中使用using_filters返回的整数索引的要求,我认为有更好的选择。如果你要从using_filters中删除np.where:

def using_filters(data):
    return np.logical_and.reduce(
        [data == f(data, footprint=np.ones((3,3)), mode='constant', cval=np.inf)
         for f in (filters.maximum_filter, filters.minimum_filter)])

then using_filters would return a boolean mask. Using a boolean mask would make this problem even easier:

然后using_filters将返回一个布尔掩码。使用布尔掩码会使这个问题更容易:

import numpy as np
import scipy.ndimage.filters as filters

def using_filters(data):
    return np.logical_and.reduce(
        [data == f(data, footprint=np.ones((3,3)), mode='constant', cval=np.inf)
         for f in (filters.maximum_filter, filters.minimum_filter)])


data  = np.array([[0,1,2,3,4,7,6,7,8,9,10], 
        [3,3,3,4,7,7,7,8,11,12,11],  
        [3,3,3,5,7,7,7,9,11,11,11],
        [3,4,3,6,7,7,7,10,11,11,11],
        [4,5,6,7,7,9,10,11,11,11,11]], dtype='float')

result = using_filters(data)
data[~result] = np.nan
print data
# [[ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]
#  [ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]
#  [ nan  nan  nan  nan  nan   7.  nan  nan  nan  nan  nan]
#  [ nan  nan  nan  nan  nan  nan  nan  nan  nan  11.  nan]
#  [ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]]

#3


2  

You can get the values you want from data, and fill data with nan and then copy the values back to data:

您可以从数据中获取所需的值,并使用nan填充数据,然后将值复制回数据:

import numpy as np
data  = np.array([[0,1,2,3,4,7,6,7,8,9,10], 
        [3,3,3,4,7,7,7,8,11,12,11],  
        [3,3,3,5,7,7,7,9,11,11,11],
        [3,4,3,6,7,7,7,10,11,11,11],
        [4,5,6,7,7,9,10,11,11,11,11]], float)

result = np.where(data==7) 

values = data[result]
data.fill(np.nan)
data[result] = values

#1


2  

There must be a better way but this is the best I can think of right now. Make another array of all np.nan, and then replace the values at the indices in result with the real values:

必须有一个更好的方法,但这是我现在能想到的最好的方法。创建所有np.nan的另一个数组,然后将结果中的索引处的值替换为实际值:

data_nan = np.full(data.shape, np.nan)
data_nan[result] = data[result]
data = data_nan

If you want to get a list of all indices that are not in result, you could do this, though I think the above is probably better:

如果你想得到一个没有结果的所有索引的列表,你可以这样做,虽然我认为上面可能更好:

inc = np.core.rec.fromarrays(result)
all_ind = np.core.rec.fromarrays(np.indices(data.shape).reshape(2,-1))
exc = np.setdiff1d(all_ind, inc)
data[exc['f0'], exc['f1']] = np.nan

This works by turning each pair of indices into one element of a structured array, so that they can be compared as set elements to a similar array of all indices. Then we do the set difference of these and get the rest.

这通过将每对索引转换为结构化数组的一个元素来工作,因此可以将它们作为集合元素与所有索引的类似数组进行比较。然后我们做这些的设定差异,并得到其余的。

#2


3  

Use the 3-argument form of np.where:

使用np.where的3参数形式:

In [49]: np.where(data==7, data, np.nan)
Out[49]: 
array([[ nan,  nan,  nan,  nan,  nan,   7.,  nan,   7.,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,   7.,   7.,  nan,  nan,  nan,  nan,  nan,  nan]])

or

要么

In [62]: np.choose(data==7, [np.nan, data])
Out[62]: 
array([[ nan,  nan,  nan,  nan,  nan,   7.,  nan,   7.,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,   7.,   7.,   7.,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,   7.,   7.,  nan,  nan,  nan,  nan,  nan,  nan]])

Regarding the requirement that the integer indices returned by using_filters be used in this solution, I think there is a better alternative. If you were to remove the np.where from using_filters:

关于在此解决方案中使用using_filters返回的整数索引的要求,我认为有更好的选择。如果你要从using_filters中删除np.where:

def using_filters(data):
    return np.logical_and.reduce(
        [data == f(data, footprint=np.ones((3,3)), mode='constant', cval=np.inf)
         for f in (filters.maximum_filter, filters.minimum_filter)])

then using_filters would return a boolean mask. Using a boolean mask would make this problem even easier:

然后using_filters将返回一个布尔掩码。使用布尔掩码会使这个问题更容易:

import numpy as np
import scipy.ndimage.filters as filters

def using_filters(data):
    return np.logical_and.reduce(
        [data == f(data, footprint=np.ones((3,3)), mode='constant', cval=np.inf)
         for f in (filters.maximum_filter, filters.minimum_filter)])


data  = np.array([[0,1,2,3,4,7,6,7,8,9,10], 
        [3,3,3,4,7,7,7,8,11,12,11],  
        [3,3,3,5,7,7,7,9,11,11,11],
        [3,4,3,6,7,7,7,10,11,11,11],
        [4,5,6,7,7,9,10,11,11,11,11]], dtype='float')

result = using_filters(data)
data[~result] = np.nan
print data
# [[ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]
#  [ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]
#  [ nan  nan  nan  nan  nan   7.  nan  nan  nan  nan  nan]
#  [ nan  nan  nan  nan  nan  nan  nan  nan  nan  11.  nan]
#  [ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]]

#3


2  

You can get the values you want from data, and fill data with nan and then copy the values back to data:

您可以从数据中获取所需的值,并使用nan填充数据,然后将值复制回数据:

import numpy as np
data  = np.array([[0,1,2,3,4,7,6,7,8,9,10], 
        [3,3,3,4,7,7,7,8,11,12,11],  
        [3,3,3,5,7,7,7,9,11,11,11],
        [3,4,3,6,7,7,7,10,11,11,11],
        [4,5,6,7,7,9,10,11,11,11,11]], float)

result = np.where(data==7) 

values = data[result]
data.fill(np.nan)
data[result] = values