Страницы

Поиск по вопросам

Показаны сообщения с ярлыком nan. Показать все сообщения
Показаны сообщения с ярлыком nan. Показать все сообщения

понедельник, 23 декабря 2019 г.

numpy выдаёт nan для corrcoeff

#python #python_3x #python_2x #numpy #nan


numpy отдаёт nan. Если есть два разных массива, то вылетают nan:

np.corrcoef([0.1, 0.1, 0.1], [0.9, 0.9, 0.9])
array([[  1.,  nan],
       [ nan,  nan]])


Если два одинаковых массива, то этого не происходит:

np.corrcoef([0.1, 0.1, 0.1], [0.1, 0.1, 0.1])
array([[ 1.,  1.],
   [ 1.,  1.]])


Также непонятно, почему corrcoef отдаёт все nan для нулей:

np.corrcoef([0, 0, 0], [0.1, 0.1, 0.1])
array([[  nan,  nan],
       [ nan,  nan]])

    


Ответы

Ответ 1



Если смоделировать то что происходит внутри функции np.corrcoef(): In [37]: x=[0.1, 0.1, 0.1]; y=[0.9,0.9,0.9] # расчет ковариционной матрицы In [38]: c = np.cov(x,y) # для указанных значений - она имеет нулевые значения для 3-х из 4-х элементов # в результате `np.corrcoef()` на месте этих элементов будут стоять NaN In [39]: c Out[39]: array([[ 2.88889492e-34, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00]]) In [40]: d = np.diag(c) In [41]: d Out[41]: array([ 2.88889492e-34, 0.00000000e+00]) In [42]: stddev = np.sqrt(d.real) In [43]: stddev Out[43]: array([ 1.69967494e-17, 0.00000000e+00]) В следующей строке мы получим NaN как результат деления на ноль: In [44]: c /= stddev[:, None] ...\py36\Scripts\ipython3:1: RuntimeWarning: invalid value encountered in true_divide In [45]: stddev[:, None] Out[45]: array([[ 1.69967494e-17], [ 0.00000000e+00]]) In [46]: c Out[46]: array([[ 1.69967494e-17, 0.00000000e+00], [ nan, nan]]) Как это обойти - прибавить очень маленькое число к одному или нескольким элементам второго массива: In [109]: x=[0.1, 0.1, 0.1]; y=[0.9,0.9,0.9+1e-16] In [110]: np.corrcoef(x,y) Out[110]: array([[ 1. , -0.57735027], [-0.57735027, 1. ]]) или In [111]: x=np.array([0.1, 0.1, 0.1]); y=np.array([0.9,0.9,0.9])+1e-16 In [112]: np.corrcoef(x,y) Out[112]: array([[ 1., -1.], [-1., 1.]])

Удаление строк DataFrame, содержащих NaN в определенном столбце

#python #pandas #dataframe #nan


Необходимо удалить все строки DataFrame, где значение столбца filename равно NaN. 
Код:
for n in range(len(df_common_fin)):
    if df_common_fin.iloc[n, 'filename'] == np.nan:
        df_common_fin.drop(index=n)

не работает, хотя прохожу по порядковым индексам iloc. Выдается ошибка:


  ValueError: Location based indexing can only have [integer, integer slice (START
point is INCLUDED, END point is EXCLUDED), listlike of integers, boolean array] types


такой код:

for n in range(len(df_common_fin)):
if df_common_fin['filename'][n] == np.nan:
    df_common_fin.drop(index=n,axis=0)


так же выдаешь ошибку:


  KeyError: 0

    


Ответы

Ответ 1



Воспользуйтесь методом DataFrame.dropna(subset=['colX','colY']): df_common_fin = df_common_fin.dropna(axis='index', how='any', subset=['filename']) Ошибка в вашем коде вызвана тем что "accessor" df.iloc[] воспринимает только позиционные аргументы, как для индекса, так и для столбцов. Т.е. df_common_fin.iloc[n, 'filename'] надо переписать так: df_common_fin.iloc[n, ] Следующая проблема, которая бы у вас возникла это: np.nan != np.nan - как следствие конструкция if ... всегда была бы ложной: In [139]: np.nan == np.nan Out[139]: False In [140]: np.nan != np.nan Out[140]: True т.е. одна "неопределенность" не обязательно равна другой "неопределенности". Поэтому в Pandas существуют функции для работы с NaN: pd.isna, pd.isnull pd.nontna, pd.notnull DataFrame.isna, DataFrame.isnull DataFrame.notna, DataFrame.notnull DataFrame.dropna

воскресенье, 1 декабря 2019 г.

Смысловая нагрузка значения “минус NaN”

#cpp #nan


В другом вопросе обнаружилось, что деление нуля на переменную, содержащую вещественный
ноль, в результате даёт значение -nan.

#include 

int main()
{
    double zero = 0;
    std::cout << 0/zero << "\n";
}


Результат получается одинаковым для основных наиболее популярных компиляторов:


Clang
GCC
MSVC


Есть ли какой-то практический смысл в этом минусе, почему не просто nan?
    


Ответы

Ответ 1



Получается это из-за того, что все вышеозначенные примеры были запущены на x86 архитектуре, а для FPU оной есть такое правило: When neither of the source operands is a NaN, but the operation generates a floating-point invalid-operation exception (see Tables 8-10 and 11-1), the result is commonly a QNaN FP Indefinite (Section 4.8.3.7). Взятое из Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture параграфа 4.8.3.5. Заглянув в таблицу, указанную в цитате выше, мы обнаружим там следующую операцию, которая даёт на выходе QNaN: Division: ∞ by ∞ ; 0 by 0. Т.е. как раз то, что у нас и есть в вопросе (там есть и другие операции). А если мы посмотрим на таблицу 4-3, из секции 4.2.2, то увидим, что у QNaN знаковый бит выставлен в 1, что объясняет появление отрицательного NaN в выводе. А если посмотреть на это всё с точки зрения языка, то получается неопределённое поведение, поэтому видеть мы можем всё, что угодно. C++14, [expr]p4: If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. Ответ навеян замечательный постом от Реймонда Чена.

понедельник, 26 ноября 2018 г.

numpy выдаёт nan для corrcoeff

Не пойму, почему numpy отдаёт nan. Если есть два разных массива, то вылетают nan
np.corrcoef([0.1, 0.1, 0.1], [0.9, 0.9, 0.9]) array([[ 1., nan], [ nan, nan]])
При этом, если два одинаковых массива, то этого не происходит:
np.corrcoef([0.1, 0.1, 0.1], [0.1, 0.1, 0.1]) array([[ 1., 1.], [ 1., 1.]])
Также непонятно, почему corrcoef отдаёт все nan для нулей:
np.corrcoef([0, 0, 0], [0.1, 0.1, 0.1]) array([[ nan, nan], [ nan, nan]])


Ответ

Если смоделировать то что происходит внутри функции np.corrcoef()
In [37]: x=[0.1, 0.1, 0.1]; y=[0.9,0.9,0.9]
# расчет ковариционной матрицы In [38]: c = np.cov(x,y)
# для указанных значений - она имеет нулевые значения для 3-х из 4-х элементов # в результате `np.corrcoef()` на месте этих элементов будут стоять NaN In [39]: c Out[39]: array([[ 2.88889492e-34, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00]])
In [40]: d = np.diag(c)
In [41]: d Out[41]: array([ 2.88889492e-34, 0.00000000e+00])
In [42]: stddev = np.sqrt(d.real)
In [43]: stddev Out[43]: array([ 1.69967494e-17, 0.00000000e+00])
В следующей строке мы получим NaN как результат деления на ноль:
In [44]: c /= stddev[:, None] ...\py36\Scripts\ipython3:1: RuntimeWarning: invalid value encountered in true_divide
In [45]: stddev[:, None] Out[45]: array([[ 1.69967494e-17], [ 0.00000000e+00]])
In [46]: c Out[46]: array([[ 1.69967494e-17, 0.00000000e+00], [ nan, nan]])
Как это обойти - прибавить очень маленькое число к одному или нескольким элементам второго массива:
In [109]: x=[0.1, 0.1, 0.1]; y=[0.9,0.9,0.9+1e-16]
In [110]: np.corrcoef(x,y) Out[110]: array([[ 1. , -0.57735027], [-0.57735027, 1. ]])
или
In [111]: x=np.array([0.1, 0.1, 0.1]); y=np.array([0.9,0.9,0.9])+1e-16
In [112]: np.corrcoef(x,y) Out[112]: array([[ 1., -1.], [-1., 1.]])

пятница, 5 октября 2018 г.

Смысловая нагрузка значения “минус NaN”

В другом вопросе обнаружилось, что деление нуля на переменную, содержащую вещественный ноль, в результате даёт значение -nan
#include
int main() { double zero = 0; std::cout << 0/zero << "
"; }
Результат получается одинаковым для основных наиболее популярных компиляторов:
Clang GCC MSVC
Есть ли какой-то практический смысл в этом минусе, почему не просто nan?


Ответ

Получается это из-за того, что все вышеозначенные примеры были запущены на x86 архитектуре, а для FPU оной есть такое правило:
When neither of the source operands is a NaN, but the operation generates a floating-point invalid-operation exception (see Tables 8-10 and 11-1), the result is commonly a QNaN FP Indefinite (Section 4.8.3.7).
Взятое из Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture параграфа 4.8.3.5.
Заглянув в таблицу, указанную в цитате выше, мы обнаружим там следующую операцию, которая даёт на выходе QNaN:
Division: ∞ by ∞ ; 0 by 0.
Т.е. как раз то, что у нас и есть в вопросе (там есть и другие операции). А если мы посмотрим на таблицу 4-3, из секции 4.2.2, то увидим, что у QNaN знаковый бит выставлен в 1, что объясняет появление отрицательного NaN в выводе.

А если посмотреть на это всё с точки зрения языка, то получается неопределённое поведение, поэтому видеть мы можем всё, что угодно.
C++14, [expr]p4:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

Ответ навеян замечательный постом от Реймонда Чена.