Как определить, что отрицательные значения являются неизменными при использовании таблицы поиска в Numpy - PullRequest
0 голосов
/ 17 декабря 2018

Я использую справочную таблицу для замены значений моей матрицы b в соответствии с массивом a.Мои данные заполнены отрицательным значением (-9999) для представления «нет данных» для моего окончательного анализа.Из-за инвертированного индекса моя выходная матрица не соответствует ожиданиям (см .: -9999 превращается в 22).Есть ли способ определить, что отрицательное значение остается неизменным?Если я использую только положительные значения, код работает нормально, но это не мой случай = /.Спасибо заранее !!

a = np.asarray([[1, 11], [2, 22], [3, 33], [10000, 555]], dtype=np.int32)
b = np.asarray([[0, 1, 2, 3, -9999], [0, 1, 2, 10000, -9999], [0, 1, 2, 3, -9999], [0, 1, 2, 3, -9999]])
lut = np.arange(b.max()+1) #look up table
#creating equation to result in output
k,v = a.T
lut[k] = v
out_matrix = lut[b]

выходы:

ref table...
[[    1    11]
 [    2    22]
 [    3    33]
 [10000   555]]

lookup table...
[    0     1     2 ...,  9998  9999 10000] 

matrix to change...
[[    0     1     2     3 -9999]
 [    0     1     2 10000 -9999]
 [    0     1     2     3 -9999]
 [    0     1     2     3 -9999]]

out_matrix...
[[  0  11  22  33  22]
 [  0  11  22 555  22]
 [  0  11  22  33  22]
 [  0  11  22  33  22]]

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Решение 1:

Так как вам нужно, чтобы все остальные индексы работали нормально, просто используйте np.where EDIT: @Paul Panzer указывает, однако, что это не работает, если -9999недопустимый индекс для поиска.

import numpy as np
a = np.asarray([[1, 11], [2, 22], [3, 33], [10000, 555]], dtype=np.int32)
b = np.asarray([[0, 1, 2, 3, -9999], [0, 1, 2, 10000, -9999], [0, 1, 2, 3, -9999], [0, 1, 2, 3, -9999]])
lut = np.arange(b.max()+1) #look up table
#creating equation to result in output
k,v = a.T
lut[k] = v
out_matrix = np.where(b!=-9999,lut[b],-9999)

Вывод:

array([[    0,    11,    22,    33, -9999],
       [    0,    11,    22,   555, -9999],
       [    0,    11,    22,    33, -9999],
       [    0,    11,    22,    33, -9999]])

Решение 2:

Если хитрость не сработает, некоторые хитрости наверняка могут сработать,Используйте таблицу поиска, чтобы создать дополнительный поиск.Оберните функцию, если вам нужно выполнить эту операцию несколько раз.

import numpy as np

def masked_lookup(lut, lookup_array, mask_value = -9999):
    '''Performs a lookup for all values except a mask_value, 
     set to -9999 by default. Uses Array indexing and points
     the masked value to itself in the lookup. '''
    lut_with_mask = np.zeros(len(lut) + 1, dtype=np.int32)
    lut_with_mask[:-1] = lut
    lut_with_mask[-1] = mask_value
    lookup_array[lookup_array == mask_value] = len(lut)
    return lut_with_mask[lookup_array]

a = np.asarray([[1, 11], [2, 22], [3, 33], [1000, 555]], dtype=np.int32)
b = np.asarray([[0, 1, 2, 3, -9999], [0, 1, 2, 1000, -9999], [0, 1, 2, 3, -9999], [0, 1, 2, 3, -9999]])
max_value = b.max()
lut = np.arange(max_value + 1) #look up table
#creating equation to result in output
k,v = a.T
lut[k] = v
out_matrix = masked_lookup(lut, b)

Вывод:

array([[    0,    11,    22,    33, -9999],
       [    0,    11,    22,   555, -9999],
       [    0,    11,    22,    33, -9999],
       [    0,    11,    22,    33, -9999]])
0 голосов
/ 17 декабря 2018

Просто добавьте необходимое количество (9999) манекенов в конце вашей лютни.Затем [-9999] будет ссылаться на первый из этих манекенов, и вы можете установить его на что угодно.

NV = -9999
a = np.asarray([[1, 11], [2, 22], [3, 33], [10000, 555]], dtype=np.int32)
b = np.asarray([[0, 1, 2, 3, -9999], [0, 1, 2, 10000, -9999], [0, 1, 2, 3, -9999], [0, 1, 2, 3, -9999]])
lut = np.arange(b.max()+1-NV) #look up table
lut[NV] = NV
#creating equation to result in output
k,v = a.T
lut[k] = v
out_matrix = lut[b]

out_matrix
# array([[    0,    11,    22,    33, -9999],
#        [    0,    11,    22,   555, -9999],
#        [    0,    11,    22,    33, -9999],
#        [    0,    11,    22,    33, -9999]])

Если вас беспокоит потеря памяти, вы можете использовать stride_tricks следующим образом:

NV = -9999
a = np.asarray([[1, 11], [2, 22], [3, 33], [10000, 555]], dtype=np.int32)
b = np.asarray([[0, 1, 2, 3, -9999], [0, 1, 2, 10000, -9999], [0, 1, 2, 3, -9999], [0, 1, 2, 3, -9999]])
lut = np.arange(b.max()+2) #look up table
lut[-1] = NV
lut = np.lib.stride_tricks.as_strided(lut, (lut.size-1-NV,), lut.strides)
#creating equation to result in output
k,v = a.T
lut[k] = v
out_matrix = lut[b]

out_matrix
# array([[    0,    11,    22,    33, -9999],
#        [    0,    11,    22,   555, -9999],
#        [    0,    11,    22,    33, -9999],
#        [    0,    11,    22,    33, -9999]])

Предупреждение: Неправильное использование может позволить вам получить доступ к памяти за пределами.Вы должны быть уверены, что никогда не ссылаетесь ни на что, кроме 0 ... max (b) или NV.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...