Изменения Pandas inplace fillna означают

#python #pandas #dataframe #imputation

#python #панды #фрейм данных #вменение

Вопрос:

У меня есть фрейм данных с отсутствующими значениями в некоторых столбцах. Я хочу заполнить эти пропущенные значения средним значением не пропущенных записей в том же столбце. Легко показать, что среднее значение не должно меняться после вменения среднего. Например, скажем, в столбце m отсутствуют записи, а сумма n не пропущенных записей равна s . Шаг вменения среднего значения заменит недостающие записи средним s/n значением . Среднее значение после этой замены должно быть

 mean_after = ((s/n)*m   s)/(m n) = s/n = mean_before_replacement
 

Я думаю, что это разумное ожидание. Однако pandas, похоже, нарушает этот инвариант. Вот пример :

 >>> import pandas as pd
>>> pd.__version__
'1.1.0'
>>> df = pd.read_csv("dftest.csv")
>>> df.describe()
                 a
count  1057.000000
mean      1.228950
std       0.420356
min       1.000000
25%       1.000000
50%       1.000000
75%       1.000000
max       2.000000
>>> df.notna().sum()
a    1057
dtype: int64
>>> df.isna().sum()
a    260
dtype: int64
>>> mean_before = df.a.mean()
>>> mean_before
1.2289498580889309
>>> df.fillna(dict(df.mean()), inplace=True)
>>> mean_after = df.a.mean()
>>> mean_after
1.228949858088931
>>> mean_before == mean_after
False
 

Я что-то здесь упускаю?

Комментарии:

1. docs.python.org/3/tutorial/floatingpoint.html

2. любопытно, какова ваша научная область, где требуется точность до 10 ^ -15

3. @PaulH Спасибо. Основная проблема, с которой я сталкиваюсь, заключается в том, что фрейм данных сериализуется после этапа вменения. Эти данные позже вводятся в регрессионную модель после этапа масштабирования (ноль 1 и std 1). Я недостаточно знаю о числовой стабильности алгоритмов оптимизации, чтобы утверждать, что это усечение вызывает проблему.

Ответ №1:

Я полагаю, вы видите машинный эпсилон. Обычно нас учили, что арифметика с плавающей запятой была точной только примерно до 15 цифр после десятичной дроби.

Если я не ошибаюсь, вы можете умножить все значения на одно и то же число (например, 1000), выполнить арифметику, а затем разделить на то же число, чтобы сохранить точность. Другим решением было бы округление до 14-й цифры, чтобы это утверждение было истинным.

Математическое объяснение см. В Этом сообщении math SO.