Мне нужно написать функцию, которая будет определять, содержит ли вход хотя бы одно нечисловое значение. Если будет найдено нечисловое значение, я вызову ошибку (поскольку расчет должен возвращать только числовое значение). Количество измерений входного массива заранее не известно - функция должна выдавать правильное значение независимо от ndim. В качестве дополнительного усложнения входные данные могут быть одним числом с плавающей запятой numpy.float64
или даже чем-то необычным, например, нулевым массивом.
Очевидный способ решить эту проблему - написать рекурсивную функцию, которая выполняет итерацию по каждому итерируемому объекту в массиве, пока не найдет не повторяющийся. Он будет применять numpy.isnan()
функцию ко всем не повторяемым объектам. Если будет найдено хотя бы одно нечисловое значение, функция немедленно вернет False. В противном случае, если все значения в итерируемом объекте являются числовыми, он в конечном итоге вернет True.
Это работает нормально, но довольно медленно, и я ожидаю, что у NumPy есть гораздо лучший способ сделать это. Какая альтернатива более быстрая и простая?
Вот мой макет:
def contains_nan( myarray ):
"""
@param myarray : An n-dimensional array or a single float
@type myarray : numpy.ndarray, numpy.array, float
@returns: bool
Returns true if myarray is numeric or only contains numeric values.
Returns false if at least one non-numeric value exists
Not-A-Number is given by the numpy.isnan() function.
"""
return True
contains_nan
выглядит подозрительно: «Возвращает false, если существует хотя бы одно нечисловое значение». Я ожидал,contains_nan
что вернусь,True
если массив содержит NaN.array(['None', 'None'], dtype=object)
? Должен ли такой ввод просто вызывать исключение?float('nan') in x
. Это не работает.Ответы:
Это должно быть быстрее, чем повторение, и будет работать независимо от формы.
Изменить: в 30 раз быстрее:
Полученные результаты:
Бонус: он отлично работает для типов NumPy без массива:
источник
float('nan') in x
не работает? Я попробовал, и python вернетсяFalse
гдеx = [1,2,3,float('nan')]
.numpy.any
genexp просто возвращает genexp; вы на самом деле не выполняете вычисления, о которых думаете. Никогда не обращайтесьnumpy.any
к генэксп.np.isfinite
а неnp.isnan
обнаруживать числовые переполнения, нестабильность и т. Д.Если бесконечность - возможное значение, я бы использовал numpy.isfinite
Если приведенное выше значение равно
True
, то неmyarray
содержит значенийnumpy.nan
,numpy.inf
или-numpy.inf
.numpy.nan
будет нормально соnumpy.inf
значениями, например:источник
float('nan') in x
не работает? Я попробовал, и python вернетсяFalse
гдеx = [1,2,3,float('nan')]
.nan
s не считаются равными друг другу. Попробуйfloat('nan') == float('nan')
.Пфф! Микросекунды! Никогда не решайте проблему за микросекунды, которую можно решить за наносекунды.
Обратите внимание, что принятый ответ:
Лучшее решение - немедленно вернуть True при обнаружении NAN:
и работает для n-измерений:
Сравните это с собственным решением numpy:
Метод раннего выхода - это ускорение на 3 порядка (в некоторых случаях). Не так уж и плохо для простой аннотации.
источник
С numpy 1.3 или svn вы можете сделать это
Обработка nans в сравнениях не согласовывалась в более ранних версиях.
источник
float('nan') in x
не работает? Я попробовал, и python вернетсяFalse
гдеx = [1,2,3,float('nan')]
.float("nan")==float("nan")
giveFalse
(хотя возможно, он должен вернуть NAN или None). Точно так же странность с NAN и boolen NULL верна для многих языков, включая SQL (где NULL = NULL никогда не бывает истиной).(np.where(np.isnan(A)))[0].shape[0]
будет больше, чем0
еслиA
содержит хотя бы один элементnan
,A
может бытьn x m
матрицей.Пример:
источник