[Перевод] Обзор типов данных Pandas

Python Программа перевода самородков pandas искусственный интеллект

article header image

Введение

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

Хотя Pandas работает хорошо, в какой-то момент анализа данных вам может понадобиться явно преобразовать данные из одного типа в другой. В этой статье мы обсудим основные типы данных Pandas (т.е.dtypes), как они сопоставляются с типами данных python и numpy, а также несколько способов преобразования из одного типа Pandas в другой.

Типы данных панд

Типы данных — это, по сути, внутренние структуры, которые языки программирования используют для понимания того, как хранить данные и манипулировать ими. Например, программа должна понимать, что вы можете сложить два числа, например 5 + 10, чтобы получить 15. Или, если это две строки, например «кошка» и «шапка», вы можете соединить (добавить) их вместе, чтобы получить «cathat».

Одна из вещей, которая может сбивать с толку в типах данных Pandas, заключается в том, что между типами данных Pandas, Python и numpy есть некоторое совпадение. В следующей таблице приведены основные моменты:

Pandas dtypeОтображение:

Pandas dtype Тип Python Типы NumPy использовать
object str string_, unicode_ текст
int64 int int_, int8, int16, int32, int64, uint8, uint16, uint32, uint64 целое число
float64 float float_, float16, float32, float64 число с плавающей запятой
bool bool bool_ Логическое значение
datetime64 NA NA дата и время
timedelta[ns] NA NA Разница во времени
category NA NA список текстовых значений конечной длины

В большинстве случаев вам не нужно беспокоиться о явном приведении типов pandas к соответствующим типам NumPy. В общем, используйте Pandas по умолчаниюint64иfloat64может. Единственная причина, по которой я сделал эту таблицу, заключается в том, что иногда вы можете видеть типы Numpy между строками кода или во время собственного анализа.

В этой статье я сосредоточусь на следующих типах панд:

  • object
  • int64
  • float64
  • datetime64
  • bool

Если вам интересно, я напишу еще одну статью, посвященную введениюcategoryиtimedeltaтип. Однако основные методы, изложенные в этой статье, применимы и к этим типам.

Почему мы заботимся о типах?

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

Я буду использовать очень простойCSV-файлЧтобы проиллюстрировать некоторые распространенные ошибки, вызванные типами данных, с которыми вы можете столкнуться в Pandas. Так же есть пример на гитхабеnotbook.

import numpy as np
import pandas as pd

df = pd.read_csv("sales_data_types.csv")
Customer Number Customer Name 2016 2017 Percent Growth Jan Units Month Day Year Active
0 10002.0 Quest Industries $125,000.00 $162500.00 30.00% 500 1 10 2015 Y
1 552278.0 Smith Plumbing $920,000.00 $101,2000.00 10.00% 700 6 15 2014 Y
2 23477.0 ACME Industrial $50,000.00 $62500.00 25.00% 125 3 29 2016 Y
3 24900.0 Brekke LTD $350,000.00 $490000.00 4.00% 75 10 27 2015 Y
4 651029.0 Harbor Co $15,000.00 $12750.00 -15.00% Closed 2 2 2014 N

На первый взгляд данные выглядят нормально, поэтому мы можем попытаться что-то сделать для анализа данных. Попробуем сложить продажи за 2016 и 2017 годы:

df['2016'] + df['2017']
0      $125,000.00$162500.00
1    $920,000.00$101,2000.00
2        $50,000.00$62500.00
3      $350,000.00$490000.00
4        $15,000.00$12750.00
dtype: object

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

Если мы хотим видеть все типы данных в кадре данных, используйтеdf.dtypes

df.dtypes
Customer Number    float64
Customer Name       object
2016                object
2017                object
Percent Growth      object
Jan Units           object
Month                int64
Day                  int64
Year                 int64
Active              object
dtype: object

также,df.info()Функции могут отображать больше полезной информации.

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 10 columns):
Customer Number    5 non-null float64
Customer Name      5 non-null object
2016               5 non-null object
2017               5 non-null object
Percent Growth     5 non-null object
Jan Units          5 non-null object
Month              5 non-null int64
Day                5 non-null int64
Year               5 non-null int64
Active             5 non-null object
dtypes: float64(1), int64(3), object(6)
memory usage: 480.0+ bytes

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

  • Customer Numberклассифицироваться какfloat64но это должно бытьint64
  • 2016и2017Эти два столбца хранятся какobject, но должно бытьfloat64илиint64такой числовой тип
  • Percent GrowthиJan Unitsтакже хранится какobjectвместо числовых типов
  • Month,DayиYearЭти три столбца должны быть преобразованы вdatetime64
  • Activeстолбец должен быть логическим

Очень сложно провести дополнительный анализ этих данных, пока мы не очистим эти типы данных.

Для преобразования типов данных в Pandas есть три основных варианта:

  • использоватьastype()принуждать к соответствующемуdtype
  • Создайте пользовательскую функцию для преобразования данных
  • Используйте функции Pandas, такие какto_numeric()илиto_datetime()

использоватьastype()функция

Самый простой способ преобразовать столбец данных Pandas в другой тип — использоватьastype(). Например, чтобыCustomer NumberЧтобы преобразовать в целое число, мы можем вызвать его следующим образом:

df['Customer Number'].astype('int')
0     10002
1    552278
2     23477
3     24900
4    651029
Name: Customer Number, dtype: int64

Чтобы фактически изменить номер клиента в исходном фрейме данных, не забудьте поставитьastype()Возвращаемое значение функции переназначается фрейму данных, потому чтоastype()Просто верните копию данных, не изменяя их на месте.

df["Customer Number"] = df['Customer Number'].astype('int')
df.dtypes
Customer Number     int64
Customer Name      object
2016               object
2017               object
Percent Growth     object
Jan Units          object
Month               int64
Day                 int64
Year                int64
Active             object
dtype: object

Вот новый кадр данных с номерами клиентов в виде целых чисел:

Customer Number Customer Name 2016 2017 Percent Growth Jan Units Month Day Year Active
0 10002 Quest Industries $125,000.00 $162500.00 30.00% 500 1 10 2015 Y
1 552278 Smith Plumbing $920,000.00 $101,2000.00 10.00% 700 6 15 2014 Y
2 23477 ACME Industrial $50,000.00 $62500.00 25.00% 125 3 29 2016 Y
3 24900 Brekke LTD $350,000.00 $490000.00 4.00% 75 10 27 2015 Y
4 651029 Harbor Co $15,000.00 $12750.00 -15.00% Closed 2 2 2014 N

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

df['2016'].astype('float')
ValueError       Traceback (most recent call last)
<ipython-input-45-999869d577b0> in <module>()
----> 1 df['2016'].astype('float')

[一些错误信息]

ValueError: could not convert string to float: '$15,000.00'

Аналогичным образом мы можем попытатьсяJan UnitsПреобразование столбцов в целые числа:

df['Jan Units'].astype('int')
ValueError         Traceback (most recent call last)

<ipython-input-44-31333711e4a4> in <module>()
----> 1 df['Jan Units'].astype('int')

[一些错误信息]


ValueError: invalid literal for int() with base 10: 'Closed'

Оба они возвращаютсяValueErrorИсключение, что означает, что преобразование не работает.

В обоих случаях данные содержат значения, которые нельзя интерпретировать как числа. В столбце Продажи (2016 г.) данные включают символ валюты и запятую в каждом значении. существуетJan UnitsВ столбце последнее значение «Закрыто», что не является числом, поэтому мы получаем исключение.

уже,astype()Как инструмент выглядит не очень. мы вActiveПопробуйте еще раз в колонке.

df['Active'].astype('bool')
0    True
1    True
2    True
3    True
4    True
Name: Active, dtype: bool

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

В центре внимания этого разделаastype()Это сработает только если:

  • Данные чистые и могут быть просто интерпретированы как число
  • вы хотите преобразовать числовое значение в строковый объект

Если данные имеют нечисловые символы или однородны среди них, тоastype()Не лучший выбор для преобразования типов. Вам нужно сделать дополнительные преобразования, чтобы сделать правильное преобразование типа.

пользовательская функция преобразования

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

Для конвертации валюты (этот конкретный набор данных) мы можем использовать простую функцию:

def convert_currency(val):
    """
    Convert the string number value to a float
     - Remove $
     - Remove commas
     - Convert to float type
    """
    new_val = val.replace(',','').replace('$', '')
    return float(new_val)

Этот код использует строковую функцию Python для удаления$и,, затем преобразуйте значение в число с плавающей запятой. В данном конкретном случае мы могли бы преобразовать значение в целое число, но я решил использовать в данном случае число с плавающей запятой.

Я также сомневаюсь, что кто-нибудь предложит использовать валюту.Decimalтип. Это не собственный тип данных Pandas, поэтому я намеренно придерживаюсь метода float.

Также стоит отметить, что функция преобразует число в pythonfloat, но Pandas внутренне преобразует его вfloat64. Как упоминалось ранее, я рекомендую вам разрешить Pandas преобразовывать его в определенный размер, когда он решит, что это уместно.floatилиint. Вам не нужно пытаться преобразовать его в меньший или больший размер байта, если вы действительно не знаете, зачем вам это нужно.

Теперь мы можем использовать PandasapplyФункция применяет его ко всем значениям в столбце 2016.

df['2016'].apply(convert_currency)
0    125000.0
1    920000.0
2     50000.0
3    350000.0
4     15000.0
Name: 2016, dtype: float64

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

Я уверен, что опытные читатели спросят, почему я не использую лямбда-функцию? Прежде чем ответить, давайте посмотрим, что мы можем использовать в одной строкеlambdaЧто делает функция:

df['2016'].apply(lambda x: x.replace('$', '').replace(',', '')).astype('float')

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

  • Если вы просто изучаете Python / Pandas, или если будет кто-то новый Python, чтобы поддерживать код в будущем, я думаю, что более длительные функции более читаются. Основная причина в том, что он может содержать комментарии или его можно разбить на шаги. Функции лямбда сложнее для новичков понять.
  • Во-вторых, если вы планируете повторно использовать эту функцию для нескольких столбцов, копировать длинную лямбда-функцию неудобно.
  • Наконец, с помощью функции можно использовать при использованииread_csv()Легко очищайте данные. Я представлю конкретный метод использования в конце статьи.

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

Используется следующееconvert_currencyПолный пример функции, преобразующей данные в двух столбцах продаж (2016/2017).

df['2016'] = df['2016'].apply(convert_currency)
df['2017'] = df['2017'].apply(convert_currency)

df.dtypes
Customer Number      int64
Customer Name       object
2016               float64
2017               float64
Percent Growth      object
Jan Units           object
Month                int64
Day                  int64
Year                 int64
Active              object
dtype: object

Об использованииlambdaи еще один пример функции, которую мы можем посмотреть, чтобы исправитьPercent Growthпроцесс колонки.

использоватьlambda:

df['Percent Growth'].apply(lambda x: x.replace('%', '')).astype('float') / 100

Сделайте то же самое с пользовательской функцией:

def convert_percent(val):
    """
    Convert the percentage string to an actual floating point percent
    - Remove %
    - Divide by 100 to make decimal
    """
    new_val = val.replace('%', '')
    return float(new_val) / 100

df['Percent Growth'].apply(convert_percent)

Оба возвращают одно и то же значение:

0    0.30
1    0.10
2    0.25
3    0.04
4   -0.15
Name: Percent Growth, dtype: float64

Последняя пользовательская функция, о которой я расскажу, это использованиеnp.where()Преобразуйте столбец Active в логическое значение. Есть много способов решить эту конкретную проблему.np.where()Методы полезны для многих типов проблем, поэтому я решил представить их здесь.

Основная идея заключается в использованииnp.where()функция будет всеYзначение преобразуется вTrue, все остальные значенияFalse

df["Active"] = np.where(df["Active"] == "Y", True, False)

Результатом является следующий кадр данных:

Customer Number Customer Name 2016 2017 Percent Growth Jan Units Month Day Year Active
0 10002.0 Quest Industries $125,000.00 $162500.00 30.00% 500 1 10 2015 True
1 552278.0 Smith Plumbing $920,000.00 $101,2000.00 10.00% 700 6 15 2014 True
2 23477.0 ACME Industrial $50,000.00 $62500.00 25.00% 125 3 29 2016 True
3 24900.0 Brekke LTD $350,000.00 $490000.00 4.00% 75 10 27 2015 True
4 651029.0 Harbor Co $15,000.00 $12750.00 -15.00% Closed 2 2 2014 False

dtype правильно установлен вbool.

df.dtypes
Customer Number    float64
Customer Name       object
2016                object
2017                object
Percent Growth      object
Jan Units           object
Month                int64
Day                  int64
Year                 int64
Active                bool
dtype: object

все, что вы решите использоватьlambdaфункцию, создайте более стандартную функцию Python или используйте другие методы, такие какnp.where), эти методы очень гибкие и могут быть настроены в соответствии с вашими уникальными потребностями в данных.

Вспомогательные функции Pandas

Панды простыastype()Существует средняя земля между функциями и сложными пользовательскими функциями. Эти функции помощника полезны для определенных преобразований типа данных.

Если вы прочитаете это по порядку, то заметите, что у меня нет столбца даты илиJan UnitsКолонки делают что угодно. Оба типа столбцов могут использовать встроенные функции Pandas (например,pd.to_numeric()иpd.to_datetime()) для преобразования.

Jan UnitsПреобразование проблематично, поскольку столбец содержит нечисловое значение. Если мы попытаемся использоватьastype(), получаем ошибку (как было сказано ранее).pd.to_numeric()Функции могут более изящно обрабатывать эти значения:

pd.to_numeric(df['Jan Units'], errors='coerce')
0    500.0
1    700.0
2    125.0
3     75.0
4      NaN
Name: Jan Units, dtype: float64

Здесь стоит отметить несколько вещей. Во-первых, функция легко обрабатывает данные и создаетfloat64Список. Кроме того, он будет использоватьNaNподстановка значения недействительнаClosedзначение, потому что мы настроилиerrors=coerce. мы можем поставитьNanоставайтесь там, также можете использоватьfillna(0)дополнить его 0s:

pd.to_numeric(df['Jan Units'], errors='coerce').fillna(0)
0    500.0
1    700.0
2    125.0
3     75.0
4      0.0
Name: Jan Units, dtype: float64

Преобразование, которое я закончил, заключалось в преобразовании отдельных столбцов месяца, дня и года вdatetimeтип столбца. Пандыpd.to_datetime()функцияНастраиваемый, но и вполне разумен по умолчанию.

pd.to_datetime(df[['Month', 'Day', 'Year']])
0   2015-01-10
1   2014-06-15
2   2016-03-29
3   2015-10-27
4   2014-02-02
dtype: datetime64[ns]

В этом случае функция объединяет столбцы в соответствующиеdatateime64Новый столбец для dtype.

Нам нужно обязательно присвоить эти значения обратно фрейму данных:

df["Start_Date"] = pd.to_datetime(df[['Month', 'Day', 'Year']])
df["Jan Units"] = pd.to_numeric(df['Jan Units'], errors='coerce').fillna(0)
Customer Number Customer Name 2016 2017 Percent Growth Jan Units Month Day Year Active Start_Date
0 10002 Quest Industries 125000.0 162500.0 0.30 500.0 1 10 2015 True 2015-01-10
1 552278 Smith Plumbing 920000.0 1012000.0 0.10 700.0 6 15 2014 True 2014-06-15
2 23477 ACME Industrial 50000.0 62500.0 0.25 125.0 3 29 2016 True 2016-03-29
3 24900 Brekke LTD 350000.0 490000.0 0.04 75.0 10 27 2015 True 2015-10-27
4 651029 Harbor Co 15000.0 12750.0 -0.15 NaN 2 2 2014 False 2014-02-02

Теперь данные корректно конвертируются во все нужные нам типы:

df.dtypes
Customer Number             int64
Customer Name              object
2016                      float64
2017                      float64
Percent Growth            float64
Jan Units                 float64
Month                       int64
Day                         int64
Year                        int64
Active                       bool
Start_Date         datetime64[ns]

Датафрейм готов к анализу!

сложить их вместе

следует использовать как можно раньше в процессе сбора данныхastype()и пользовательские функции преобразования. Если у вас есть файл данных, предназначенный для многократной обработки, и он всегда хранится в одном и том же формате, вы можете определить, что необходимо применять при чтении данных.dtypeиconverters. будетdtypeсчитается выполненным на данныхastype()Очень полезно.convertersПараметры позволяют применять функции к различным входным столбцам, аналогично методам, описанным выше.

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

Ниже приведен упрощенный пример, он завершает почти все преобразования при чтении данных DataFrame:

df_2 = pd.read_csv("sales_data_types.csv",
                   dtype={'Customer Number': 'int'},
                   converters={'2016': convert_currency,
                               '2017': convert_currency,
                               'Percent Growth': convert_percent,
                               'Jan Units': lambda x: pd.to_numeric(x, errors='coerce'),
                               'Active': lambda x: np.where(x == "Y", True, False)
                              })

df_2.dtypes
Customer Number      int64
Customer Name       object
2016               float64
2017               float64
Percent Growth     float64
Jan Units          float64
Month                int64
Day                  int64
Year                 int64
Active              object
dtype: object

Как упоминалось ранее, я решил включить данные, используемые для преобразованияlambdaПримеры и примеры функций. Единственная функция, которую здесь нельзя использовать, это та, которая преобразуетMonth,DayиYearПреобразовать три столбца вdatetimeфункция столбца. Тем не менее, это мощное соглашение, которое может помочь улучшить процесс обработки данных.

Суммировать

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


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллекти другие поля, если вы хотите видеть больше качественных переводов, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.