Перейти к содержимому

Isna python что это

  • автор:

pandas.DataFrame.isna#

Return a boolean same-sized object indicating if the values are NA. NA values, such as None or numpy.NaN , gets mapped to True values. Everything else gets mapped to False values. Characters such as empty strings » or numpy.inf are not considered NA values (unless you set pandas.options.mode.use_inf_as_na = True ).

Mask of bool values for each element in DataFrame that indicates whether an element is an NA value.

Boolean inverse of isna.

Omit axes labels with missing values.

Show which entries in a DataFrame are NA.

>>> df = pd.DataFrame(dict(age=[5, 6, np.nan], . born=[pd.NaT, pd.Timestamp('1939-05-27'), . pd.Timestamp('1940-04-25')], . name=['Alfred', 'Batman', ''], . toy=[None, 'Batmobile', 'Joker'])) >>> df age born name toy 0 5.0 NaT Alfred None 1 6.0 1939-05-27 Batman Batmobile 2 NaN 1940-04-25 Joker 
>>> df.isna() age born name toy 0 False True False True 1 False False False False 2 True False False False 

Show which entries in a Series are NA.

>>> ser = pd.Series([5, 6, np.nan]) >>> ser 0 5.0 1 6.0 2 NaN dtype: float64 
>>> ser.isna() 0 False 1 False 2 True dtype: bool 

Проверка на наличие NaN в DataFrame в Pandas

Detecting missing values in data with Python and Pandas.

Часто при работе с большими наборами данных, особенно теми, которые были получены из внешних источников, могут возникать проблемы с пропущенными или недоступными данными. В Python и библиотеке Pandas такие данные обычно представлены значением NaN (Not a Number).

Рассмотрим пример DataFrame:

import pandas as pd import numpy as np data = < 'A': [1, 2, np.nan], 'B': [5, np.nan, np.nan], 'C': [1, 2, 3] >df = pd.DataFrame(data)

В этом DataFrame в столбцах ‘A’ и ‘B’ есть значения NaN.

Варианты проверки наличия NaN

Вариант 1: isnull() и any()

Один из способов проверить наличие NaN в DataFrame — использовать функцию isnull() . Она возвращает другой DataFrame, где каждое значение это булево значение, указывающее, является ли соответствующее значение в исходном DataFrame NaN.

df.isnull()

Чтобы узнать, есть ли хотя бы одно значение NaN в DataFrame, можно использовать функцию any() , которая возвращает True, если хотя бы одно значение в DataFrame является True.

df.isnull().any().any()

Вариант 2: isna() и values

Альтернативный способ — использовать функцию isna() , которая аналогична isnull() . Однако, вместо второго any() можно использовать свойство values и функцию any() из numpy.

np.any(df.isna().values)

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

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

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

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

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

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

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

# import the libraries import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline import matplotlib as plt import matplotlib as mpl import matplotlib.cm as cm import matplotlib.pyplot as plt from matplotlib import pyplot # import the dataset train_df = pd.read_csv(r'C:\Users\Tatiana\Desktop\Python\titanic\train.csv') train_df.head(2)

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

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

train_df.shape

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

train_df.describe()

метод describe( )

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

# describe all the columns train_df.describe(include = "all")

метод describe(include =

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

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

# look at the info print(train_df.info())

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

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

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

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

train_df['Survived'].value_counts()

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

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

sns.set_style('whitegrid') sns.countplot(x='Survived',data=train_df,palette='RdBu_r')

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

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

figure, survive_bar = plt.subplots(figsize=(7, 7)) sns.barplot(x= train_df["Survived"].value_counts().index, y = train_df["Survived"].value_counts(), ax = survive_bar) survive_bar.set_xticklabels(['Not Survived', 'Survived']) survive_bar.set_ylabel('Frequency Count') survive_bar.set_title('Count of Survival', fontsize = 16) for patch in survive_bar.patches: label_x = patch.get_x() + patch.get_width()/2 # find midpoint of rectangle label_y = patch.get_y() + patch.get_height()/2 survive_bar.text(label_x, label_y, #left - freq below - rel freq wrt population as a percentage str(int(patch.get_height())) + '(' + ''.format(patch.get_height()/len(train_df.Survived))+')', horizontalalignment='center', verticalalignment='center')

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

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

fig, myplot = plt.subplots(figsize = (15,6), nrows = 2,ncols = 3) features = ["Survived","Pclass","Sex","SibSp","Parch","Embarked"] row, col, num_cols = 0,0,3 for u in features: sns.barplot(x = train_df[u].value_counts().index,y = train_df[u].value_counts(), ax = myplot[row, col]) myplot[row, col].set_xlabel("") myplot[row, col].set_title(u + " Titanic", fontsize = 15) myplot[row, col].set_ylabel("Count") col = col + 1 if col == 3: col = 0 row = row + 1 plt.subplots_adjust(hspace = 0.5) plt.subplots_adjust(wspace = 0.3) # i put roundbracket around x,y,z to make more sense. just like how x \in [1,2,3] # and if x is a tuple or bracket #we have u \in [(1,2,3),(2,3,5). ] where u = (x,y,z) #for each patch in each graph from [0,0] to [1,2], we want to do the following. for v in range(2): for z in range(3): for patch in myplot[v,z].patches: label_x = patch.get_x() + patch.get_width()/2 # find midpoint of rectangle label_y = patch.get_y() + patch.get_height()/2 myplot[v,z].text(label_x, label_y, str(int(patch.get_height())) + '('+''.format( patch.get_height()/len(train_df.Survived))+')', horizontalalignment='center', verticalalignment='center')

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

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

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

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

# Evaluating for Missing Data missing_data = train_df.isnull() missing_data.head(6)

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

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

# Count missing values in each column for column in missing_data.columns.values.tolist(): print(column) print(missing_data[column].value_counts()) print(" ")

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

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

train_df.isnull().sum()

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

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

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

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

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

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

# missing age or not train_df.groupby(train_df['Age'].isnull()).mean()

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

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

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

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

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

# Value Counts train_df['Pclass'].value_counts()

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

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

train_df.groupby(['Pclass']) ['Survived'].value_counts(normalize=True)

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

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

# Let's create a new column 'Age_NaN' # If there is no value in the "Age" column, then = 0 and yes value = 1 train_df['Age_NaN'] = np.where(train_df['Age'].isnull(), 0,1) train_df.head(6)

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

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

# Value Counts train_df['Age_NaN'].value_counts()

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

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

# Survived passengers by 'Age_NaN' train_df.groupby(['Age_NaN']) ['Survived'].value_counts(normalize=True)

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

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

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

train_df.groupby(['Age_NaN','Pclass']) ['Survived'].value_counts(normalize=True)

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

pd.crosstab(train_df['Pclass'], train_df['Age_NaN'])

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

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

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

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

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

train_df.groupby(['Age_NaN','Sex']) ['Survived'].value_counts(normalize=True)

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

pd.crosstab(train_df['Sex'], train_df['Age_NaN'])

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

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

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

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

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

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

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

# missing values are replaced by the average value train_df['Age'].fillna(train_df['Age'].mean(), inplace = True) sns.set_style('whitegrid') %matplotlib inline g = sns.FacetGrid(train_df, col='Survived') g.map(plt.hist, 'Age', bins=10)

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

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

# Survived passengers by Pclass and Age grid = sns.FacetGrid(train_df, col ='Survived', row ='Pclass', height = 3.5, aspect=1.5) grid.map(plt.hist, 'Age', alpha=.5, bins=10) grid.add_legend();

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

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

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

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

# missing cabin or not # Relationship between the presence of a value in the "Cabin" column on the survival rate train_df.groupby(train_df['Cabin'].isnull()).mean() 

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

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

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

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

# Let's create a new column 'Cabin_available' # If there is no value in the "Cabin" column, then = 0 and yes value = 1 train_df['Cabin_available'] = np.where(train_df['Cabin'].isnull(), 0,1) train_df.head(6) 

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

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

train_df.groupby(['Cabin_available']) ['Survived'].value_counts(normalize=True)

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

train_df.pivot_table( 'PassengerId', 'Cabin_available', 'Survived', 'count').plot( kind='bar', stacked=True)

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

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

train_df.drop(['Cabin'], axis = 1, inplace = True) train_df

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

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

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

train_df['Embarked'].value_counts()

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

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

# replace the missing 'Embarked' values by the most frequent - S train_df['Embarked'].replace(np.nan, 'S', inplace = True) train_df['Embarked'].describe()

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

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

train_df.isnull().sum()

10 приемов Python Pandas, которые сделают вашу работу более эффективной

Pandas — это широко используемый пакет Python для структурированных данных. Существует много хороших учебных пособий на данную тематику, но здесь мы бы хотели раскрыть несколько интересных приемов, которые, вероятно, еще пока неизвестны читателю, но могут оказаться крайне полезными.

read_csv

Все знают эту команду. Но если данные, которые вы пытаетесь прочитать, слишком большие, попробуйте добавить команду nrows = 5 , чтобы прочитать сначала небольшую часть данных перед загрузкой всей таблицы. В этом случае вам удастся избежать ситуации выбора неверного разделителя (не всегда в данных есть разделение в виде запятой).

(Или вы можете использовать команду ‘head’ в linux для проверки первых 5 строк в любом текстовом файле: head -c 5 data.txt )

Затем вы можете извлечь список столбцов, используя df.columns.tolist() , а затем добавить команду usecols = [‘c1’, ‘c2’,…], чтобы извлечь только нужные вам столбцы. Кроме того, если вы знаете типы данных определенных столбцов, вы можете добавить dtype = для более быстрой загрузки. Еще одно преимущество этой команды в том, что если у вас есть столбец, который содержит как строки, так и числа, рекомендуется объявить его тип строковым, чтобы не возникало ошибок при попытке объединить таблицы, используя этот столбец в качестве ключа.

select_dtypes

Если предварительная обработка данных должна выполняться в Python, то эта команда сэкономит ваше время. После чтения из таблицы типами данных по умолчанию для каждого столбца могут быть bool, int64, float64, object, category, timedelta64 или datetime64. Вы можете сначала проверить распределение с помощью

df.dtypes.value_counts()

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

df.select_dtypes(include=[‘float64’, ‘int64’])

чтобы выбрать субфрейм только с числовыми характеристиками.

сopy

Это важная команда. Если вы сделаете:

import pandas as pd
df1 = pd.DataFrame(< ‘a’:[0,0,0], ‘b’: [1,1,1]>)
df2 = df1
df2[‘a’] = df2[‘a’] + 1
df1.head()

Вы обнаружите, что df1 изменен. Это потому, что df2 = df1 не делает копию df1 и присваивает ее df2, а устанавливает указатель, указывающий на df1. Таким образом, любые изменения в df2 приведут к изменениям в df1. Чтобы это исправить, вы можете сделать либо:

df2 = df1.copy ()
from copy import deepcopy
df2 = deepcopy(df1)

map

Это классная команда для простого преобразования данных. Сначала вы определяете словарь, в котором «ключами» являются старые значения, а «значениями» являются новые значения.

level_map = 
df[‘c_level’] = df[‘c’].map(level_map)

Например: True, False до 1, 0 (для моделирования); определение уровней; определяемые пользователем лексические кодировки.

apply or not apply?

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

def rule(x, y): 
if x == ‘high’ and y > 10:
return 1
else:
return 0

df = pd.DataFrame(< 'c1':[ 'high' ,'high', 'low', 'low'], 'c2': [0, 23, 17, 4]>)
df['new'] = df.apply(lambda x: rule(x['c1'], x['c2']), axis = 1)
df.head()

В приведенных выше кодах мы определяем функцию с двумя входными переменными и используем функцию apply, чтобы применить ее к столбцам ‘c1’ и ‘c2’.

но проблема «apply» заключается в том, что иногда она занимает очень много времени.

Скажем, если вы хотите рассчитать максимум из двух столбцов «c1» и «c2», конечно, вы можете применить данную команду

df[‘maximum’] = df.apply(lambda x: max(x[‘c1’], x[‘c2’]), axis = 1)

но это будет медленнее, нежели:

df[‘maximum’] = df[[‘c1’,’c2']].max(axis =1)

Вывод: не используйте команду apply, если вы можете выполнить ту же работу используя другие функции (они часто быстрее). Например, если вы хотите округлить столбец ‘c’ до целых чисел, выполните округление (df [‘c’], 0) вместо использования функции apply.

value counts

Это команда для проверки распределения значений. Например, если вы хотите проверить возможные значения и частоту для каждого отдельного значения в столбце «c», вы можете применить

df[‘c’].value_counts()

Есть несколько полезных приемов / функций:
A. normalize = True : если вы хотите проверить частоту вместо подсчетов.
B. dropna = False : если вы хотите включить пропущенные значения в статистику.
C. sort = False : показать статистику, отсортированную по значениям, а не по количеству.

D. df[‘c].value_counts().reset_index().: если вы хотите преобразовать таблицу статистики в датафрейм Pandas и управлять ими.

количество пропущенных значений

При построении моделей может потребоваться исключить строку со слишком большим количеством пропущенных значений / строки со всеми пропущенными значениями. Вы можете использовать .isnull () и .sum () для подсчета количества пропущенных значений в указанных столбцах.

import pandas as pd
import numpy as np

df = pd.DataFrame(< ‘id’: [1,2,3], ‘c1’:[0,0,np.nan], ‘c2’: [np.nan,1,1]>)
df = df[[‘id’, ‘c1’, ‘c2’]]
df[‘num_nulls’] = df[[‘c1’, ‘c2’]].isnull().sum(axis=1)
df.head()

выбрать строки с конкретными идентификаторами

В SQL мы можем сделать это, используя SELECT * FROM… WHERE ID в («A001», «C022»,…), чтобы получить записи с конкретными идентификаторами. Если вы хотите сделать то же самое с pandas, вы можете использовать:

df_filter = df ['ID']. isin (['A001', 'C022', . ]) 
df [df_filter]

Percentile groups

Допустим, у вас есть столбец с числовыми значениями, и вы хотите классифицировать значения в этом столбце по группам, скажем, топ 5% в группу 1, 5–20% в группу 2, 20–50% в группу 3, нижние 50% в группу 4. Конечно, вы можете сделать это с помощью pandas.cut, но мы бы хотели представить другую функцию:

import numpy as np
cut_points = [np.percentile(df[‘c’], i) for i in [50, 80, 95]]
df[‘group’] = 1
for i in range(3):
df[‘group’] = df[‘group’] + (df[‘c’] < cut_points[i])
# or Которая быстро запускается (не применяется функция apply).

to_csv

Опять-таки, это команда, которую используют все. Отметим пару полезных приемов. Первый:
print(df[:5].to_csv())

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

Еще один прием касается смешанных вместе целых чисел и пропущенных значений. Если столбец содержит как пропущенные значения, так и целые числа, тип данных по-прежнему будет float, а не int. Когда вы экспортируете таблицу, вы можете добавить float_format = '%. 0f', чтобы округлить все числа типа float до целых чисел. Используйте этот прием, если вам нужны только целочисленные выходные данные для всех столбцов – так вы избавитесь от всех назойливых нулей ‘.0’ .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *