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

Nan python что это

  • автор:

Not a Number — все о NaN / pd 5

В предыдущих разделах вы видели, как легко могут образовываться недостающие данные. В структурах они определяются как значения NaN (Not a Value). Такой тип довольно распространен в анализе данных.

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

Присваивание значения NaN

Если нужно специально присвоить значение NaN элементу структуры данных, для этого используется np.NaN (или np.nan ) из библиотеки NumPy.

>>> ser = pd.Series([0,1,2,np.NaN,9], ... index=['red','blue','yellow','white','green']) >>> ser red 0.0 blue 1.0 yellow 2.0 white NaN green 9.0 dtype: float64 
>>> ser['white'] = None >>> ser red 0.0 blue 1.0 yellow 2.0 white NaN green 9.0 dtype: float64 

Фильтрование значений NaN

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

>>> ser.dropna() red 0.0 blue 1.0 yellow 2.0 green 9.0 dtype: float64 

Функцию фильтрации можно выполнить и прямо с помощью notnull() при выборе элементов.

>>> ser[ser.notnull()] red 0.0 blue 1.0 yellow 2.0 green 9.0 dtype: float64 

В случае с Dataframe это чуть сложнее. Если использовать функцию pandas dropna() на таком типе объекта, который содержит всего одно значение NaN в колонке или строке, то оно будет удалено.

>>> frame3 = pd.DataFrame([[6,np.nan,6],[np.nan,np.nan,np.nan],[2,np.nan,5]], ... index = ['blue','green','red'], ... columns = ['ball','mug','pen']) >>> frame3 
ball mug pen
blue 6.0 NaN 6.0
green NaN NaN NaN
red 2.0 NaN 5.0
>>> frame3.dropna() Empty DataFrame Columns: [ball, mug, pen] Index: [] 

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

>>> frame3.dropna(how='all') 
ball mug pen
blue 6.0 NaN 6.0
red 2.0 NaN 5.0

Заполнение NaN

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

>>> frame3.fillna(0) 
ball mug pen
blue 6.0 0.0 6.0
green 0.0 0.0 0.0
red 2.0 0.0 5.0

Или же NaN можно заменить на разные значения в зависимости от колонки, указывая их и соответствующие значения.

>>> frame3.fillna('ball':1,'mug':0,'pen':99>) 
ball mug pen
blue 6.0 0.0 6.0
green 1.0 0.0 99.0
red 2.0 0.0 5.0

Изучаем pandas. Урок 4. Работа с пропусками в данных

Follow us on Google Plus Follow us on rss

Очень часто большие объемы данных, которые подготавливаются для последующего анализа, имеют пропуски. Для того, чтобы можно было использовать алгоритмы машинного обучения, строящие модели по этим данным, в большинстве случаев, необходимо эти пропуски чем-то и как-то заполнить. На вопрос “чем заполнять?” мы не будем отвечать в рамках данного урока, а вот на вопрос “как заполнять?” ответим.

  1. pandas и отсутствующие данные
  2. Замена отсутствующих данных
  3. Удаление объектов/столбцов с отсутствующими данными

pandas и отсутствующие данные

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

Для наших экспериментов создадим структуру DataFrame , которая будет содержать пропуски. Для этого импортируем необходимые нам библиотеки.

In [1]: import pandas as pd In [2]: from io import StringIO

После этого создадим объект в формате csv . CSV – это один из наиболее простых и распространенных форматов хранения данных, в котором элементы отделяются друг от друга запятыми, более подробно о нем можете прочитать здесь.

In [3]: data = 'price,count,percent\n1,10,\n2,20,51\n3,30,' In [4]: df = pd.read_csv(StringIO(data)) 

Полученный объект df – это DataFrame с пропусками.

In [5]: df Out[5]: price count percent 0 1 10 NaN 1 2 20 51.0 2 3 30 NaN 

В нашем примере, у объектов с индексами 0 и 2 отсутствуют данные в поле percent . Отсутствующие данные помечаются как NaN . Добавим к существующей структуре еще один объект (запись), у которого будет отсутствовать значение в поле count.

In [6]: df.loc[3] = 'price':4, 'count':None, 'percent':26.3> In [7]: df Out[7]: price count percent 0 1.0 10.0 NaN 1 2.0 20.0 51.0 2 3.0 30.0 NaN 3 4.0 NaN 26.3 

Для начала обратимся к методам из библиотеки pandas , которые позволяют быстро определить наличие элементов NaN в структурах. Если таблица небольшая, то можно использовать библиотечный метод isnull . Выглядит это так.

In [8]: pd.isnull(df) Out[8]: price count percent 0 False False True 1 False False False 2 False False True 3 False True False 

Таким образом мы получаем таблицу того же размера, но на месте реальных данных в ней находятся логические переменные, которые принимают значение False , если значение поля у объекта есть, или True , если значение в данном поле – это NaN . В дополнение к этому можно посмотреть подробную информацию об объекте, для этого можно воспользоваться методом info() .

In [9]: df.info() class 'pandas.core.frame.DataFrame'> Int64Index: 4 entries, 0 to 3 Data columns (total 3 columns): price 4 non-null float64 count 3 non-null float64 percent 2 non-null float64 dtypes: float64(3) memory usage: 128.0 bytes 

В нашем примере видно, что объект df имеет три столбца ( count , percent и price ), при этом в столбце price все объекты значимы – не NaN , в столбце count – один NaN объект, в поле percent – два NaN объекта. Можно воспользоваться следующим подходом для получения количества NaN элементов в записях.

In [10]: df.isnull().sum() Out[10]: price 0 count 1 percent 2 dtype: int64

Замена отсутствующих данных

Отсутствующие данные объектов можно заменить на конкретные числовые значения, для этого можно использовать метод fillna() . Для экспериментов будем использовать структуру df , созданную в предыдущем разделе.

In [11]: df.isnull().sum() Out[11]: price 0 count 1 percent 2 dtype: int64 In [12]: df Out[12]: price count percent 0 1.0 10.0 NaN 1 2.0 20.0 51.0 2 3.0 30.0 NaN 3 4.0 NaN 26.3 In [13]: df.fillna(0) Out[13]: price count percent 0 1.0 10.0 0.0 1 2.0 20.0 51.0 2 3.0 30.0 0.0 3 4.0 0.0 26.3 

Этот метод не изменяет текущую структуру, он возвращает структуру DataFrame , созданную на базе существующей, с заменой NaN значений на те, что переданы в метод в качестве аргумента. Данные можно заполнить средним значением по столбцу.

In [14]: df.fillna(df.mean()) Out[14]: price count percent 0 1.0 10.0 38.65 1 2.0 20.0 51.00 2 3.0 30.0 38.65 3 4.0 20.0 26.30 

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

Удаление объектов/столбцов с отсутствующими данными

Довольно часто используемый подход при работе с отсутствующими данными – это удаление записей (строк) или полей (столбцов), в которых встречаются пропуски. Для того, чтобы удалить все объекты, которые содержат значения NaN воспользуйтесь методом dropna() без аргументов.

In [15]: df.dropna() Out[15]: price count percent 1 2.0 20.0 51.0 

Вместо записей, можно удалить поля, для этого нужно вызвать метод dropna с аргументом axis=1 .

In [16]: df.dropna() Out[16]: price count percent 1 2.0 20.0 51.0 In [17]: df.dropna(axis=1) Out[17]: price 0 1.0 1 2.0 2 3.0 3 4.0 

pandas позволяет задать порог на количество не- NaN элементов. В приведенном ниже примере будут удалены все столбцы, в которых количество не- NaN элементов меньше трех.

In [18]: df.dropna(axis = 1, thresh=3) Out[18]: price count 0 1.0 10.0 1 2.0 20.0 2 3.0 30.0 3 4.0 NaN 

P.S.

Раздел: Pandas Python Машинное обучение и анализ данных Метки: Pandas, Python, Машинное обучение

Изучаем pandas. Урок 4. Работа с пропусками в данных : 4 комментария

  1. Карл 11.04.2018 Полезная статья, решила одну из моих проблем с кодом) Интересно будет узнать, ЧЕМ заполнять пропуски?
  1. writer 14.04.2018 В начале написал комментарий, частично повторив содержимое статьи))) Чем заполнять, определяется задачей, т.е. если можно заполнить средним значением, то заполняйте средним, если данные чувствительны к таким махинациям, то можно просто их выбросить.

Фильтрация значений и подготовка данных для анализа — Python: Pandas

В библиотеке Pandas реализованы различные подходы, чтобы индексировать элементы. Можно обращаться к ним по порядковому номеру или по метке. При этом есть задачи, в которых нужно отсеивать элементы по условию с использованием специальных масок. В данной задаче указание конкретных интервалов для индексов не всегда подходит.

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

Использование булевых масок

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

import pandas as pd df_clicks = pd.read_csv('./data/Cite_clicks_week.csv', index_col=0) print(df_clicks) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 1319.0 -265.0 319.0 NaN # 2 NaN 267.0 333.0 344.0 # 3 283.0 NaN 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # 6 445.0 -418.0 1409.0 445.0 # 7 481.0 NaN 481.0 409.0 

Среди показателей есть NaN -значения, которые указывают на пропуски в данных. Также есть отрицательные значения и показатели, которые существенно выше всех остальных. Это вполне обычная ситуация.

Такие значения могут влиять на точность анализа данных и даже на возможность его проведения. Поэтому аналитику приходится находить их и исправлять.

Структура DataFrame поддерживает операции среза последовательных элементов в данных по аналогии со стандартными списками:

print(df_clicks[1:5]) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 2 NaN 267.0 333.0 344.0 # 3 283.0 NaN 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 

Чтобы извлечь конкретные строки, можно использовать булевы маски. Это массивы значений True и False . Строка берется, если по ее порядковому номеру в булевой маске стоит значение True :

print(df_clicks[[True, True, False, True, False, True, False]]) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 1319.0 -265.0 319.0 NaN # 2 NaN 267.0 333.0 344.0 # 4 328.0 364.0 328.0 NaN # 6 445.0 -418.0 1409.0 445.0 

Чтобы извлечь конкретные столбцы в срезе, используется метод loc() , в параметры которого передается срез и массив меток столбцов:

print(df_clicks.loc[1:5, ['SHOP1']]) # => SHOP1 # day # 1 1319.0 # 2 NaN # 3 283.0 # 4 328.0 # 5 391.0 print(df_clicks.loc[1:5, ['SHOP1', 'SHOP3']]) # => SHOP1 SHOP3 # day # 1 1319.0 319.0 # 2 NaN 333.0 # 3 283.0 274.0 # 4 328.0 328.0 # 5 391.0 373.0 

Для больших таблиц будет неудобно вручную задавать булевы маски, как мы это делали в примерах выше. В Pandas получить маску можно с помощью логических операторов, примененных к данным:

print(df_clicks['SHOP1']  300) # => day # 1 False # 2 False # 3 True # 4 False # 5 False # 6 False # 7 False # Name: SHOP1, dtype: bool 

Чтобы получить нужные строки согласно булевой маске, достаточно передать ее в качестве индекса в DataFrame :

print(df_clicks[df_clicks['SHOP1']  300]) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 3 283.0 NaN 274.0 283.0 

Выбор нужных столбцов в таблице осуществляется по аналогии с примером выше:

print(df_clicks.loc[df_clicks['SHOP1']  300, ['SHOP1', 'SHOP3']]) # => SHOP1 SHOP3 # day # 3 283.0 274.0 

Поиск пропусков в данных

Одной из существенных проблем в данных являются пропуски. Многие функции агрегации, обработки и даже простые арифметические операции не могут быть выполнены при их наличии. Чтобы обнаружить пропуски, в Pandas используют метод isna() :

print(df_clicks[df_clicks['SHOP1'].isna()]) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 2 NaN 267.0 333.0 344.0 

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

print(df_clicks[~df_clicks['SHOP1'].isna()]) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 1319.0 -265.0 319.0 NaN # 3 283.0 NaN 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # 6 445.0 -418.0 1409.0 445.0 # 7 481.0 NaN 481.0 409.0 

Данный метод применим не только к столбцам, но и ко всей таблице:

print(df_clicks.isna()) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 False False False True # 2 True False False False # 3 False True False False # 4 False False False True # 5 False False False False # 6 False False False False # 7 False True False False 

Замена пропусков на определенные значения

Когда мы находим пропуски в данных, это помогает контролировать их качество. Но часто приходится не только их находить, но и исправлять.

В качестве значения, на которое заменяется пропуск, можно взять среднее по всем данным. Чтобы найти среднее, нужно дважды применить метод mean() , поскольку после первого применения получается массив средних для каждого магазина по отдельности:

df_clicks_mean = df_clicks.mean().mean() print(df_clicks_mean) # => 366.94 

Чтобы заполнить пропуски, используется метод fillna() с параметром, на который происходит замена пропущенных значений:

print(df_clicks.fillna(df_clicks_mean)) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 1319.00000 -265.00000 319.0 366.94881 # 2 366.94881 267.00000 333.0 344.00000 # 3 283.00000 366.94881 274.0 283.00000 # 4 328.00000 364.00000 328.0 366.94881 # 5 391.00000 355.00000 373.0 337.00000 # 6 445.00000 -418.00000 1409.0 445.00000 # 7 481.00000 366.94881 481.0 409.00000 

Замена значений в данных согласно условию

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

Анализ данных и поиск выбросов приводит к формированию некоторого условия, которому должны удовлетворять элементы. Если элементы ему не удовлетворяют, то данные значения можно заменить на среднее. Для этого используют метод where() :

print(df_clicks.where(df_clicks  1000, df_clicks_mean)) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 366.94881 -265.00000 319.00000 366.94881 # 2 366.94881 267.00000 333.00000 344.00000 # 3 283.00000 366.94881 274.00000 283.00000 # 4 328.00000 364.00000 328.00000 366.94881 # 5 391.00000 355.00000 373.00000 337.00000 # 6 445.00000 -418.00000 366.94881 445.00000 # 7 481.00000 366.94881 481.00000 409.00000 

При работе с Pandas это условие формируется в виде булевой маски. Для удобства ее выносят в отдельную переменную:

mask = (0  df_clicks) & (df_clicks  1000) print(mask) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 False False True False # 2 False True True True # 3 True False True True # 4 True True True False # 5 True True True True # 6 True False False True # 7 True False True True 
print(df_clicks.where( mask, df_clicks_mean, ) ) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 366.94881 366.94881 319.00000 366.94881 # 2 366.94881 267.00000 333.00000 344.00000 # 3 283.00000 366.94881 274.00000 283.00000 # 4 328.00000 364.00000 328.00000 366.94881 # 5 391.00000 355.00000 373.00000 337.00000 # 6 445.00000 366.94881 366.94881 445.00000 # 7 481.00000 366.94881 481.00000 409.00000 

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Булевы операции и функции, значения inf и nan

Продолжаем знакомство с операциями над массивами и посмотрим как они ведут себя с булевыми операциями. Предположим, имеется одномерный массив:

a = np.array([1, 2, 3, 10, 20, 30])

и мы хотим определить все числа, которые больше 5. Мы с вами уже выполняли такую операцию и для этого сначала формировали булевый массив, а затем, выделяли элементы, у индексов которых стоит значение True:

indx = a > 5 a[indx]

На выходе получим массив из трех элементов, которым соответствуют позиции True:

Видите, как это может быть удобно: выделить нужные элементы, не используя ни одного оператора цикла языка Python. А, значит, такая конструкция будет работать достаточно быстро (так как внутри реализована на языках Си и Fortran).

Конечно, эту запись можно еще упростить и записать в виде:

a[ a > 5 ]

Результат будет тем же. По аналогии работают и другие булевы операторы:

Здесь в качестве операндов a и b могут выступать как числа, так и массивы NumPy. Например, добавим еще один массив:

b = np.array([1, 2, 3, 4, 5, 6])

Тогда можно использовать сравнения:

a == b # array([ True, True, True, False, False, False]) a >= b # array([ True, True, True, True, True, True]) a  b # array([ True, True, True, False, False, False]) a != b # array([False, False, False, True, True, True])

Функции greater, less, equal

  • greater(a, b) – выполняет сравнение a > b;
  • less(a, b) – выполняет сравнение a < b;
  • equal(a, b) – выполняет сравнение a == b.
np.greater(a, b) # array([False, False, True, False]) np.less(a, b) # array([ True, True, False, False]) np.equal(a, b) # array([False, False, False, True])

Но, чаще всего на практике вместо них записывают булевы операторы: >, <, ==.

Функции array_equal, all и any

Но использовать результат сравнения в условных операторах нельзя. Следующая строчка приведет к ошибке:

if(a == b): print("a == b")

Для такого сравнения массивов необходимо получать только одно значение True или False, а не объект array. Для этого в пакете NumPy существуют специальная функция np.array_equal(), которую можно применить так:

if np.array_equal(a ,b): print("a == b")

Это условие сработает, если оба массива a и b содержат одинаковые значения элементов и равны по длине. Если нам нужно определить, что хотя бы один элемент массива удовлетворяет указанному условию, то можно воспользоваться функцией any(), например:

# для массива a = array([ 1, 2, 3, 10, 20, 30]) np.any(a > 5) # True np.any(a == 5) # False np.any(a == b) # True

Если же нужно узнать, все ли элемента массива удовлетворяют условию, то используется функция all():

np.all(a > 5) # False np.all(a > 0) # True np.all(a == b) # False

Значения -inf, inf и nan

Пакет NumPy реализован максимально дружественным способом и там, где можно избежать ошибок и продолжить вычисления, он это делает. Например, давайте разделим все значения массива a на 0. Из математики мы знаем, что на 0 делить нельзя, но, тем не менее, критической ошибки не возникнет, а все элементы примут значение inf:

с результатом: :1: RuntimeWarning: divide by zero encountered in true_divide array([[inf, inf],
[inf, inf],
[inf, inf]]) Здесь NumPy нас лишь предупредил, что встретилось деление на ноль, но расчеты были завершены и все элементы равны inf. Что это за значение inf? Это сокращение от английского слова infinity – бесконечность. Действительно, при делении на 0 получаем бесконечность. Именно это и указано в значениях элементов массива. Благодаря использованию этого специального значения, NumPy избежал ошибки деления на 0. Причем, inf – это полноценный элемент массивов. Его можно непосредственно задать при определении:

b = np.array([1, 2, np.inf])

И, далее, он может участвовать в вычислениях. Например, умножим b на ноль и посмотрим, что получится:

b*0 # array([ 0., 0., nan])

Последний элемент превратился в nan. Это еще одно сокращение от английского: not a number (не число) То есть, значение nan указывает, что в результате арифметической операции третий элемент перестал быть каким-либо числовым значением. Причем, это определение оказывается «прилипчивым». Например, сложим все элементы массива:

c = b*0
c.sum() # nan

То есть, любые арифметические операции с nan приводят к nan.

Функции isnan и isinf

Так как элементы inf и nan не относятся к числам, то для их идентификации, проверки, что текущий элемент массива принимает одно из этих значений, существуют функции isnan() и isinf(). Они возвращают True, если элемент равен nan и inf и Flase – в противном случае. Посмотрим как можно их использовать в программе. Пусть имеется массив:

b = np.array([1, 2, np.nan, np.inf, -np.inf])

к которому применим эти две функции:

np.isinf(b) # array([False, False, False, True, True]) np.isnan(b) # array([False, False, True, False, False])

На выходе имеем массив с булевыми значениями и True стоит на местах inf (при вызове isinf) и nan (при вызове isnan). Далее, используя этот массив можно исключить нечисловые элементы из массива, например, так:

indx = np.isinf(b) b[~indx] # array([ 1., 2., nan])

Здесь исключаются все элементы inf, а операция ~indx инвертирует булевы значения. Аналогично можно отфильтровать значения nan.

Дополнительные функции: isfinite, iscomplex, isreal

Часто, при работе с массивами требуется определить: являются ли его элементы конечными числами. Для этого используется еще одна функция – isfinit():

# для массива b = np.array([1, 2, np.nan, np.inf, -np.inf]) np.isfinite(b) # array([ True, True, False, False, False])

Соответственно, все не числовые элементы помечены как False, а числовые – как True. Далее, мы можем уточнять тип числа: комплексное или действительное, с помощью функций iscompex() и isreal(). Например:

a = np.array([1+2j, 3-4j, 5]) # array([1.+2.j, 3.-4.j, 5.+0.j]) np.iscomplex(a) # array([ True, True, False])

Обратите внимание, несмотря на то, что тип данных у всех элементов массива complex128 (посмотреть можно через a.dtype), последний элемент функция iscomplex() пометила как False, так как мнимая часть равна нулю. Аналогично работает функция isreal():

np.isreal(a) # array([False, False, True])

Только теперь True помечены действительные числа, а False – все остальные. Но, применяя эту функцию к массиву b:

np.isreal(b) # array([ True, True, True, True, True])

получим все значения True. То есть, специальные значения nan и inf отмечаются как действительные.

Функции logical_and, logical_or, logical_not и logical_xor

В NumPy можно выполнять стандартные булевы операции И, ИЛИ, НЕ, исключающее ИЛИ, применительно к данным массивов. Например, зададим два массива так, чтобы попарно элементы образовывали все возможные комбинации:

X = np.array([True, False, True, False]) Y = np.array([True, True, False, False])

И, затем, применим к ним логические операции:

np.logical_and(X, Y) # логическое И: array([ True, False, False, False]) np.logical_or(X, Y) # логическое ИЛИ: array([False, True, False, True]) np.logical_not(X) # логическое НЕ: array([False, True, False, True]) np.logical_xor(X, Y) # XOR: array([ True, True, True, True])

Получили вполне ожидаемые результаты в соответствии с таблицами истинности этих операций. Все те же операции можно проводить и с числовыми значениями, полагая, что 0 – это False, а любое другое число – True. Например, два таких массива:

a = np.array([1, 0, 2, 0]) b = np.array([3, 4, 0, 0])

Будут вести себя идентично массивам X, Y при булевых операциях:

np.logical_and(a, b) # array([ True, False, False, False])

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

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