Pandas как заменить nan на среднее

от admin

pandas DataFrame: replace nan values with average of columns

I’ve got a pandas DataFrame filled mostly with real numbers, but there is a few nan values in it as well.

How can I replace the nan s with averages of columns where they are?

This question is very similar to this one: numpy array: replace nan values with average of columns but, unfortunately, the solution given there doesn’t work for a pandas DataFrame.

12 Answers 12

You can simply use DataFrame.fillna to fill the nan ‘s directly:

The docstring of fillna says that value should be a scalar or a dict, however, it seems to work with a Series as well. If you want to pass a dict, you could use df.mean().to_dict() .

Apply per-column the mean of that columns and fill

Although, the below code does the job, BUT its performance takes a big hit, as you deal with a DataFrame with # records 100k or more:

In my experience, one should replace NaN values (be it with Mean or Median), only where it is required, rather than applying fillna() all over the DataFrame.

I had a DataFrame with 20 variables, and only 4 of them required NaN values treatment (replacement). I tried the above code (Code 1), along with a slightly modified version of it (code 2), where i ran it selectively .i.e. only on variables which had a NaN value

Below is the performance i observed, as i kept on increasing the # records in DataFrame

pandas DataFrame: заменить значения nan на среднее значение столбцов

У меня есть pandas DataFrame, заполненный в основном действительными числами, но в нем есть несколько значений nan .

Как заменить nan на средние значения столбцов, где они есть?

Этот вопрос очень похож на этот: массив numpy: замените значения nan на среднее число столбцов, но, к сожалению, решение, данное там, не работает для pandas DataFrame.

8 ответов

Вы можете просто использовать DataFrame.fillna для непосредственного заполнения nan :

fillna документа fillna говорит, что value должно быть скалярным или разборчивым, однако, похоже, что оно работает и с Series . Если вы хотите передать dict, вы можете использовать df.mean().to_dict() .

Применить для каждого столбца среднее значение этих столбцов и заполнить

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

Другой вариант, кроме вышеперечисленного, следующий:

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

Непосредственно используйте df.fillna(df.mean()) чтобы заполнить все нулевое значение средним

Если вы хотите заполнить нулевое значение средним значением этого столбца, вы можете использовать это

предположим, что x=df[‘Item_Weight’] здесь Item_Weight — это имя столбца

здесь мы присваиваем (заполняем нулевые значения х средним значением х в х)

Если вы хотите заполнить нулевое значение какой-либо строкой, используйте

здесь Outlet_size — имя столбца

Панды: Как заменить значения NaN ( nan ) на среднюю (среднюю), медиану или другую статистику одного столбца

Скажем, ваш DataFrame df и у вас есть один столбец с именем nr_items . Это: df[‘nr_items’]

Если вы хотите заменить значения NaN вашего столбца df[‘nr_items’] на среднее значение столбца:

Используйте метод .fillna :

Я создал новый столбец df именем nr_item_ave для хранения нового столбца со значениями NaN замененными mean значением столбца.

Вы должны быть осторожны при использовании mean . Если у вас есть выбросы, рекомендуется использовать median

pandas DataFrame: заменить значения nan средним значением столбцов

У меня есть pandas DataFrame, заполненный в основном реальными числами, но есть несколько nan в нем тоже ценности.

Как я могу заменить nan s со средними значениями столбцов, где они?

Этот вопрос очень похож на этот: массив numpy: заменить значения nan средним значением столбцов но, к сожалению, приведенное там решение не работает для pandas DataFrame.

задан 09 сен ’13, 00:09

12 ответы

Вы можете просто использовать DataFrame.fillna чтобы заполнить nan напрямую:

Строка документации fillna говорит, что value должен быть скаляром или диктофоном, однако, похоже, он работает с Series также. Если вы хотите передать дикт, вы можете использовать df.mean().to_dict() .

df.fillna(df.mean()) вернет новый кадр данных, поэтому вам придется написать df=df.fillna(df.mean()) сохранить его. — ЯННИС

есть идеи, почему я могу получить неправильную сумму, вмененную для среднего значения, используя это? — бернандо_виалли

Вместо df=df.fillna(df.mean()) вы также можете использовать df.fillna(df.mean(), inplace=True) — Андерсон Пиментель

ВНИМАНИЕ: если вы хотите использовать это для машинного обучения / науки о данных: с точки зрения науки о данных это неправильно чтобы сначала заменить NA, а затем разделить на обучение и тестирование. Вы ДОЛЖНЫ сначала разделить на обучение и тестирование, затем заменить NA на среднее значение в поезде, а затем применить эту модель предварительной обработки с отслеживанием состояния для тестирования, см. ответ, включающий sklearn ниже! — Фабиан Вернер

@ amalik2205 amalik100, потому что в противном случае вы пропускаете информацию из тестового набора в тренировочный набор! Представьте это так: у нас есть 99 строк данных, и мы рассматриваем столбец x. Первые 100 записей x являются NA. Мы хотим выделить строку 100 в качестве тестового набора. Предположим, что строка 20 имеет значение 20 в столбце x. Затем вы замените все записи в обучающем наборе в столбце x на 100, что соответствует XNUMX% от тестового набора. Следовательно, оценка может ввести вас в заблуждение! — Фабиан Вернер

ответ дан 16 окт ’15, 21:10

Для тех, кто интересуется inplace = True: если это True, исходный объект изменяется с этим изменением. Если это False (по умолчанию), функция не изменяет исходный объект, вместо этого она возвращает его измененную копию, и вы должны назначить ее исходному объекту, чтобы заменить ее. — hafiz031

Примените для каждого столбца среднее значение этих столбцов и заполните

Я не знаю почему, но df.fillna(df.mean()) не работал, только ваша версия с применением. Питон 3 — Ракетк

Хотя приведенный ниже код выполняет свою работу, НО его производительность сильно снижается, поскольку вы имеете дело с DataFrame с # записями 100 КБ или более:

По моему опыту, следует заменить значения NaN (будь то на Среднее или Медиана), только там, где это требуется, а не применять fillna() по всему DataFrame.

У меня был DataFrame с 20 переменными, и только 4 из них требовали обработки (замены) значений NaN. Я попробовал приведенный выше код (код 1) вместе с его слегка измененной версией (код 2), где я запускал его выборочно, то есть только для переменных, которые имели значение NaN

Ниже приведена производительность, которую я наблюдал, поскольку я продолжал увеличивать количество записей в DataFrame.

Работа с отсутствующими значениями в Pandas

Отсутствующее значение в наборе данных отображается как вопросительный знак, ноль, NaN или просто пустая ячейка. Но как можно справиться с недостающими данными?

Конечно, каждая ситуация отличается и должна оцениваться по-разному.

Есть много способов справиться с недостающими значениями. Рассмотрим типичные варианты на примере набора данных — ‘Titanic’. Эти данные являются открытым набором данных Kaggle.

Для анализа необходимо импортировать библиотеки Python и загрузить данные.

Для загрузки используется метод Pandas read.csv(). В скобках указывается путь к файлу в кавычках, чтобы Pandas считывал файл во фрейм данных (Dataframes — df) с этого адреса. Путь к файлу может быть URL адрес или вашим локальным адресом файла.

Показывает первые 2 строки загруженного фрейма данных

Показывает первые 2 строки загруженного фрейма данных

Посмотрим на размер данных (количество строк, колонок):

Для просмотра статистической сводки каждого столбца, чтобы узнать распределение данных в каждом столбце используется метод describe( ). Этот метод показывает нам количество строк в столбце — count, среднее значение столбца — mean, столбец стандартное отклонение — std, минимальные (min) и максимальные (max) значения, а также границу каждого квартиля — 25%, 50% и 75%. Любые значения NaN автоматически пропускаются.

Читать:
Adobearmservice что это за служба

метод describe( )

метод describe( )

По умолчанию, метод describe( ) пропускает строки и столбцы не содержащие чисел — категориальные признаки. Чтобы включить сводку по всем столбцам нужно в скобках добавить аргумент — include = «all».

метод describe(include = "all")

метод describe(include = «all»)

Для категориальных признаков этот метод показывает: — Сколько уникальных значений в наборе данных — unique; top значения; частота появления значений — freg.

Метод info( ) — показывает информацию о наборе данных, индекс, столбцы и тип данных, ненулевые значения и использование памяти.

показывает информацию о наборе данных, индекс, столбцы и тип данных, ненулевые значения и использование памяти.

показывает информацию о наборе данных, индекс, столбцы и тип данных, ненулевые значения и использование памяти.

В результате мы видим, что все колонки, кроме колонок ‘Age’, ‘Cabin’ и ‘Embarked’, содержат по 891 строк.

Колонка ‘Survived’ — это целевое значение. Показывает, кто выжил, а кто — нет. Эта колонка заполнена бинарными значениями:

Метод — value_counts(). Подсчет значений — это хороший способ понять, сколько единиц каждой характеристики / переменной у нас есть.

подсчет значений в колонке

подсчет значений в колонке ‘Survived’

Из 891 пассажира выжило 342.

график подсчет значений в колонке

график подсчет значений в колонке ‘Survived’

Из 891 пассажира выжило 342 это 38%.

График подсчет значений в колонке

График подсчет значений в колонке ‘Survived’

Визуализация: Графики подсчета значений в колонках — «Survived», «Pclass», «Sex», «SibSp», «Parch», «Embarked»

Графики подсчета значений в колонках - "Survived", "Pclass", "Sex", "SibSp", "Parch", "Embarked"

Графики подсчета значений в колонках — «Survived», «Pclass», «Sex», «SibSp», «Parch», «Embarked»

Теперь посмотрим на колонки которые имеют пропущенные значения.

Есть два метода обнаружения недостающих данных: — isnull() и notnull().

Результатом является логическое значение, указывающее, действительно ли значение, переданное в аргумент, отсутствует. «Истина» ( True ) означает, что значение является отсутствующим значением, а «Ложь» ( False ) означает, что значение не является отсутствующим.

True - пропущенные значения

True — пропущенные значения

Используя цикл for в Python, мы можем быстро определить количество пропущенных значений в каждом столбце. Как упоминалось выше, «Истина» представляет отсутствующее значение, а «Ложь» означает, что значение присутствует в наборе данных. В теле цикла for метод «.value_counts ()» подсчитывает количество значений «True».

количество пропущенных значений в каждом столбце.количество пропущенных значений в каждом столбце. количество пропущенных значений в каждом столбце.количество пропущенных значений в каждом столбце.

Посмотрим — сколько пропущенных значений в каждой колонке.

количество пропущенных значений в каждом столбце.

количество пропущенных значений в каждом столбце.

В колонке возраст — ‘Age’ не указано 177 значений. И нужно понять — это систематическая ошибка или какая-то случайная погрешность.

Н-р, может у пассажиров 1 класса (или у женщин) не спрашивали про возраст ( т. к. это было не прилично), или случайно пропустили. Понимание о причине пропущенных значений, определит — как работать с этими отсутствующими данными.

Нужно сгруппировать возраст, относительно того, отсутствует возраст или нет. Для группировки используем метод groupby().

True — отсутствует возраст

False — значение заполнено

метод groupby(). True - отсутствует возраст, False - значение заполнено

метод groupby(). True — отсутствует возраст, False — значение заполнено

Среди пассажиров, у которых значение возраста отсутствовало, были выжившие (около 30%) и погибшие (около 70%) — колонка ‘Survived’, True = 0.29 .

Эти пассажиры были в более низком классе:

колонка ‘Pclass’ — True = 2.59 (это среднее значение класса)

колонка ‘Fare’ — True = 22.15 (это среднее значение стоимости билета)

Подсчет значений в колонке ‘Pclass’:

Подсчет значений в колонке

Подсчет значений в колонке ‘Pclass’

Например, в 3 классе было 491 пассажира (это 55%)

Выживаемость пассажиров по классам

Выживаемость пассажиров по классам

Для более детального анализа, создадим новую колонку ‘Age_NaN’ (бинарный классификатор). Используем метод where(), где прописываем условие: — если значение в колонке ‘Age’ отсутствует, то присваиваем в колонке ‘Age_NaN’ — значение 0, если присутствует, то 1.

первые 6 строк фрейма данных с новой колонкой

первые 6 строк фрейма данных с новой колонкой ‘Age_NaN’

Подсчет значений в колонке ‘Age_NaN’

Подсчет значений в колонке

Подсчет значений в колонке ‘Age_NaN’

Выживаемость пассажиров в зависимости от наличия записи о возрасте.

Выживаемость пассажиров в зависимости от наличия записи о возрасте.

Выживаемость пассажиров в зависимости от наличия записи о возрасте.

И снова мы видим: — что, среди пассажиров, у которых значение возраста отсутствовало, были выжившие (около 30%) и погибшие (около 70%).

Выживаемость пассажиров в зависимости от наличия записи о возрасте и класса.

Выживаемость пассажиров в зависимости от наличия записи о возрасте и класса.Выживаемость пассажиров в зависимости от наличия записи о возрасте и класса.  зависимость от наличия записи о возрасте и класса.зависимость от наличия записи о возрасте и класса.

В первом классе запись отсутствует у 30 пассажиров. Из 30 пассажиров выжило — 46%(14 пассажиров), погибло — 53%(16 пассажиров). Всего пассажиров было в первом классе — 216 (в данном наборе данных).

Во втором классе запись отсутствует у 11 пассажиров. Из 11 пассажиров выжило — 36%(4 пассажира), погибло — 63% (7 пассажиров). Всего пассажиров было во втором классе — 184 (в данном наборе данных).

В третьем классе запись отсутствует у 136 пассажиров. Из 136 пассажиров выжило — 25% (34 пассажира), погибло — 75% (102 пассажира). Всего пассажиров было в третьем классе — 491 (в данном наборе данных).

Выживаемость пассажиров в зависимости от наличия записи о возрасте и пола.

Выживаемость пассажиров в зависимости от наличия записи о возрасте и пола.Выживаемость пассажиров в зависимости от наличия записи о возрасте и пола.  зависимость от наличия записи о возрасте и пола.зависимость от наличия записи о возрасте и пола.

У 53 женщин нет записи о возрасте. Из 53 женщин выжило 68% (36 женщин), погибло 32% (17 женщин). Всего женщин было — 314 (в данном наборе данных).

У 124 мужчин нет записи о возрасте. Из 124 мужчин выжило 13% (16 мужчин), погибло 87% (108 мужчин). Всего мужчин было — 577 (в данном наборе данных)

Пассажиров было много в 3 классе и много погибло. Пассажиры — мужчины, у которых был более дешевый билет и более низкий класс — имели меньше шансов выжить.

Т.к. среди пассажиров, у которых значение возраста отсутствовало, были выжившие (около 30%) и погибшие (около 70%), и пассажиры были с разных классов( из 3 класса было значительно больше), и среди пассажиров были мужчины и женщины (мужчин было значительно больше), то при опросе у выживших и при осмотре тел погибших могли случайно пропустить возраст пассажира.

Следовательно делаем вывод, что возраст случайно не занесли.

Решение: Пропущенные значения заполнить средним значением.

график выживаемости пассажиров в зависимости от возраста

график выживаемости пассажиров в зависимости от возраста

Посмотрим на график выживаемости пассажиров в зависимости от класса и возраста

график выживаемости пассажиров в зависимости от класса и возраста

график выживаемости пассажиров в зависимости от класса и возраста

В колонке каюта ( ‘Cabin’) не указано 687 значений. Т. к. пропущенных значений много, можно удалить полностью колонку ‘Cabin’, а можно и оставить отсутствующие данные как — отсутствующие данные. Здесь важно понять: — Существует ли какая-то систематическая взаимосвязь между выживанием и тем, была ли у пассажира отдельная каюта.Для группировки используем метод groupby().

True — отсутствует упоминание о каюте

False — значение заполнено

метод groupby(). True - отсутствует упоминание о каюте, False - значение заполнено

метод groupby(). True — отсутствует упоминание о каюте, False — значение заполнено

Те, пассажиры у кого запись отсутствует — выжили около 30%. А у кого запись о наличии каюты есть — выжило 67%.

Вывод: Есть взаимосвязь между выживанием и наличием каюты.

Создать новую колонку ‘Cabin_available’ (бинарный классификатор).Используем метод where(), где прописываем условие: — Если значение в колонке ‘Cabin’ отсутствует, то присваиваем в колонке ‘Cabin_available’ — значение 0, если присутствует, то 1.

показывает первые 6 строк фрейма данных с новой колонкой

показывает первые 6 строк фрейма данных с новой колонкой ‘Cabin_available’

Выживаемость пассажиров в зависимости от наличия записи о каюте:

Выживаемость пассажиров в зависимости от наличия записи о каютеВыживаемость пассажиров в зависимости от наличия записи о каюте График выживаемости пассажиров в зависимости от наличия записи о каютеГрафик выживаемости пассажиров в зависимости от наличия записи о каюте

Теперь колонку ‘Cabin’ можно удалить.

фрейм данных без колонки

фрейм данных без колонки ‘Cabin’

В колонке порт посадки на борт (‘Embarked’) не указано два значения. Это категориальный признак.

Решение: Заменить пропущенные значения по частоте. Заменить отсутствующее значение значением, которым чаще всего встречается в конкретном столбце.

подсчет значений в колонке

подсчет значений в колонке ‘Embarked’

Чаще всего встречается значение S — 644. Нужно заменить пропущенные значения на S.

метод describe() для колонки

метод describe() для колонки ‘Embarked’, после замены пропущенных значений.

Good! Now, we have a dataset with no missing values. (Хорошо! Теперь у нас есть набор данных без пропущенных значений.)

набор данных без пропущенных значенийнабор данных без пропущенных значений

Похожие статьи