Какой тип у столбца в pandas python
Перейти к содержимому

Какой тип у столбца в pandas python

  • автор:

Оперирование таблицами pandas #

Считаем таблицу с планетами и выведем типы данных в её столбце.

Количество спутников Масса Группа Кольца
Название
Меркурий 0 0.0055 земная группа Нет
Венера 0 0.8150 земная группа Нет
Земля 1 1.0000 земная группа Нет
Марс 2 0.1070 земная группа Нет
Юпитер 62 317.8000 газовый гигант Да
Сатурн 34 95.2000 газовый гигант Да
Уран 27 14.3700 ледяной гигант Да
Нептун 13 17.1500 ледяной гигант Да

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

Во-первых, значение столбца “ Кольца ” булевого характера. Чтобы сразу считать их сразу как булевые, в методе read_csv можно указать какие значения следует интерпретировать в качестве True , а какие в качестве False , параметрами true_values и false_values .

По аналогии с true_values и false_values ещё есть параметр na_values , отвечающий за пропущенные значения.

Количество спутников Масса Группа Кольца
Название
Меркурий 0 0.0055 земная группа False
Венера 0 0.8150 земная группа False
Земля 1 1.0000 земная группа False
Марс 2 0.1070 земная группа False
Юпитер 62 317.8000 газовый гигант True
Сатурн 34 95.2000 газовый гигант True
Уран 27 14.3700 ледяной гигант True
Нептун 13 17.1500 ледяной гигант True

Видим, что значения столбца “ Кольца ” автоматически приняли булевый тип.

Во-вторых, значения столбца “ Группа ” принимают одно из трех значений, а хранятся в столбце типа object . Переменные такого характера называют категориальными или номинальными. Для их хранения в pandas эффективнее будет воспользоваться специальным категориальным типом данных.

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

Видим, что метод преобразовал все к типу "category" . Эффективнее, конечно, загрузить таблицу сразу с необходимыми типами данных.

Количество спутников Масса Группа Кольца
Название
Меркурий 0 0.005500 земная группа False
Венера 0 0.815000 земная группа False
Земля 1 1.000000 земная группа False
Марс 2 0.107000 земная группа False
Юпитер 62 317.799988 газовый гигант True
Сатурн 34 95.199997 газовый гигант True
Уран 27 14.370000 ледяной гигант True
Нептун 13 17.150000 ледяной гигант True

Названия столбцов#

Иногда может потребоваться переименовать столбцы и метки строк в таблице. Переведем названия столбцов и планет, чтобы продемонстрировать принцип работы метода pd.DataFrame.rename.

number of moons mass group rings
Название
Mercury 0 0.005500 земная группа False
Venus 0 0.815000 земная группа False
Earth 1 1.000000 земная группа False
Mars 2 0.107000 земная группа False
jupyter 62 317.799988 газовый гигант True
Saturn 34 95.199997 газовый гигант True
Uranus 27 14.370000 ледяной гигант True
Neptune 13 17.150000 ледяной гигант True

Т.е. в большинстве случаев удобнее всего указать новые названия столбцов и/или новые метки индекса в виде словаря.

Обратите внимание, что по умолчанию метод rename не изменяет названия столбцов на месте, а возвращает копию таблицы с переименованными столбцами. Это стандартное поведение для многих методов pandas : в последнее время разработчики pandas стараются избегать мутирующих методов. Однако если талица очень крупная, то её копирование ради совершения простых операций может оказаться накладным. В таком случае полезным может оказаться метод inplace .

Переименовать название индекса таблицы можно методом pandas.Index.rename

Пропущенные значения#

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

s1 s2 s3
a 1.0 -1 NaN
b 2.0 NaN NaN
c NaN NaN NaN

Например, метод mean вычисляет среднее каждого столбца с численными значениями.

Overview of Pandas Data Types

article header image

When doing data analysis, it is important to make sure you are using the correct data types; otherwise you may get unexpected results or errors. In the case of pandas, it will correctly infer data types in many cases and you can move on with your analysis without any further thought on the topic.

Despite how well pandas works, at some point in your data analysis processes, you will likely need to explicitly convert data from one type to another. This article will discuss the basic pandas data types (aka dtypes ), how they map to python and numpy data types and the options for converting from one pandas type to another.

Pandas Data Types

A data type is essentially an internal construct that a programming language uses to understand how to store and manipulate data. For instance, a program needs to understand that you can add two numbers together like 5 + 10 to get 15. Or, if you have two strings such as “cat” and “hat” you could concatenate (add) them together to get “cathat.”

A possible confusing point about pandas data types is that there is some overlap between pandas, python and numpy. This table summarizes the key points:

Pandas dtype mapping

Pandas dtype Python type NumPy type Usage
object str or mixed string_, unicode_, mixed types Text or mixed numeric and non-numeric values
int64 int int_, int8, int16, int32, int64, uint8, uint16, uint32, uint64 Integer numbers
float64 float float_, float16, float32, float64 Floating point numbers
bool bool bool_ True/False values
datetime64 NA datetime64[ns] Date and time values
timedelta[ns] NA NA Differences between two datetimes
category NA NA Finite list of text values

For the most part, there is no need to worry about determining if you should try to explicitly force the pandas type to a corresponding to NumPy type. Most of the time, using pandas default int64 and float64 types will work. The only reason I included in this table is that sometimes you may see the numpy types pop up on-line or in your own analysis.

For this article, I will focus on the follow pandas types:

  • object
  • int64
  • float64
  • datetime64
  • bool

The category and timedelta types are better served in an article of their own if there is interest. However, the basic approaches outlined in this article apply to these types as well.

One other item I want to highlight is that the object data type can actually contain multiple different types. For instance, the a column could include integers, floats and strings which collectively are labeled as an object . Therefore, you may need some additional techniques to handle mixed data types in object columns. Refer to this article for an example the expands on the currency cleanups described below.

Why do we care?

Data types are one of those things that you don’t tend to care about until you get an error or some unexpected results. It is also one of the first things you should check once you load a new data into pandas for further analysis.

I will use a very simple CSV file to illustrate a couple of common errors you might see in pandas if the data type is not correct. Additionally, an example notebook is up on github.

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

Upon first glance, the data looks ok so we could try doing some operations to analyze the data. Let’s try adding together the 2016 and 2017 sales:

This does not look right. We would like to get totals added together but pandas is just concatenating the two values together to create one long string. A clue to the problem is the line that says dtype: object. An object is a string in pandas so it performs a string operation instead of a mathematical one.

If we want to see what all the data types are in a dataframe, use df.dtypes

Additionally, the df.info() function shows even more useful info.

After looking at the automatically assigned data types, there are several concerns:

  • The Customer Number is a float64 but it should be an int64
  • The 2016 and 2017 columns are stored as objects, not numerical values such as a float64 or int64
  • Percent Growth and Jan Units are also stored as objects not numerical values
  • We have Month , Day and Year columns that should be converted to datetime64
  • The Active column should be a boolean

Until we clean up these data types, it is going to be very difficult to do much additional analysis on this data.

In order to convert data types in pandas, there are three basic options:

  • Use astype() to force an appropriate dtype
  • Create a custom function to convert the data
  • Use pandas functions such as to_numeric() or to_datetime()

Using the astype() function

The simplest way to convert a pandas column of data to a different type is to use astype() . For instance, to convert the Customer Number to an integer we can call it like this:

In order to actually change the customer number in the original dataframe, make sure to assign it back since the astype() functions returns a copy.

And here is the new data frame with the Customer Number as an integer:

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

This all looks good and seems pretty simple. Let’s try to do the same thing to our 2016 column and convert it to a floating point number:

In a similar manner, we can try to conver the Jan Units column to an integer:

Both of these return ValueError exceptions which mean that the conversions did not work.

In each of the cases, the data included values that could not be interpreted as numbers. In the sales columns, the data includes a currency symbol as well as a comma in each value. In the Jan Units columnm the last value is “Closed” which is not a number; so we get the exception.

So far it’s not looking so good for astype() as a tool. We should give it one more try on the Active column.

At first glance, this looks ok but upon closer inspection, there is a big problem. All values were interpreted as True but the last customer has an Active flag of N so this does not seem right.

The takeaway from this section is that astype() will only work if:

  • the data is clean and can be simply interpreted as a number
  • you want to convert a numeric value to a string object

If the data has non-numeric characters or is not homogeneous, then astype() will not be a good choice for type conversion. You will need to do additional transforms for the type change to work correctly.

Custom Conversion Functions

Since this data is a little more complex to convert, we can build a custom function that we apply to each value and convert to the appropriate data type.

For currency conversion (of this specific data set), here is a simple function we can use:

The code uses python’s string functions to strip out the ‘$” and ‘,’ and then convert the value to a floating point number. In this specific case, we could convert the values to integers as well but I’m choosing to use floating point in this case.

I also suspect that someone will recommend that we use a Decimal type for currency. This is not a native data type in pandas so I am purposely sticking with the float approach.

Also of note, is that the function converts the number to a python float but pandas internally converts it to a float64. As mentioned earlier, I recommend that you allow pandas to convert to specific size float or int as it determines appropriate. There is no need for you to try to downcast to a smaller or upcast to a larger byte size unless you really know why you need to do it.

Now, we can use the pandas apply function to apply this to all the values in the 2016 column.

Success! All the values are showing as float64 so we can do all the math functions we need to.

I’m sure that the more experienced readers are asking why I did not just use a lambda function? Before I answer, here is what we could do in 1 line with a lambda function:

Using lambda we can streamline the code into 1 line which is a perfectly valid approach. I have three main concerns with this approach:

  • If you are just learning python/pandas or if someone new to python is going to be maintaining code, I think the longer function is more readable. The primary reason is that it includes comments and can be broken down into a couple of steps. lambda functions are a little more difficult for the new user to grasp.
  • Secondly, if you are going to be using this function on multiple columns, I prefer not to duplicate the long lambda function.
  • Finally, using a function makes it easy to clean up the data when using read_csv(). I will cover usage at the end of the article.

Some may also argue that other lambda-based approaches have performance improvements over the custom function. That may be true but for the purposes of teaching new users, I think the function approach is preferrable.

Here’s a full example of converting the data in both sales columns using the convert_currency function.

For another example of using lambda vs. a function, we can look at the process for fixing the Percent Growth column.

Using the lambda :

Doing the same thing with a custom function:

Both produce the same value:

The final custom function I will cover is using np.where() to convert the active column to a boolean. There are several possible ways to solve this specific problem. The np.where() approach is useful for many types of problems so I’m choosing to include it here.

The basic idea is to use the np.where() function to convert all “Y” values to True and everything else assigned False

Which results in the following dataframe:

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

The dtype is appropriately set to bool .

Whether you choose to use a lambda function, create a more standard python function or use another approach like np.where() , these approaches are very flexible and can be customized for your own unique data needs.

Pandas helper functions

Pandas has a middle ground between the blunt astype() function and the more complex custom functions. These helper functions can be very useful for certain data type conversions.

If you have been following along, you’ll notice that I have not done anything with the date columns or the Jan Units column. Both of these can be converted simply using built in pandas functions such as pd.to_numeric() and pd.to_datetime() .

The reason the Jan Units conversion is problematic is the inclusion of a non-numeric value in the column. If we tried to use astype() we would get an error (as described earlier). The pd.to_numeric() function can handle these values more gracefully:

There are a couple of items of note. First, the function easily processes the data and creates a float64 column. Additionally, it replaces the invalid “Closed” value with a NaN value because we passed errors=coerce . We can leave that value there or fill it in with a 0 using fillna(0) :

The final conversion I will cover is converting the separate month, day and year columns into a datetime . The pandas pd.to_datetime() function is quite configurable but also pretty smart by default.

In this case, the function combines the columns into a new series of the appropriate datateime64 dtype.

We need to make sure to assign these values back to the dataframe:

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

Now the data is properly converted to all the types we need:

The dataframe is ready for analysis!

Bringing it all together

The basic concepts of using astype() and custom functions can be included very early in the data intake process. If you have a data file that you intend to process repeatedly and it always comes in the same format, you can define the dtype and converters to be applied when reading the data. It is helpful to think of dtype as performing astype() on the data. The converters arguments allow you to apply functions to the various input columns similar to the approaches outlined above.

It is important to note that you can only apply a dtype or a converter function to a specified column once using this approach. If you try to apply both to the same column, then the dtype will be skipped.

Here is a streamlined example that does almost all of the conversion at the time the data is read into the dataframe:

As mentioned earlier, I chose to include a lambda example as well as the function example for converting data. The only function that can not be applied here is the conversion of the Month , Day and Year columns to the corresponding datetime column. Still, this is a powerful convention that can help improve your data processing pipeline.

Summary

One of the first steps when exploring a new data set is making sure the data types are set correctly. Pandas makes reasonable inferences most of the time but there are enough subtleties in data sets that it is important to know how to use the various data conversion options available in pandas. If you have any other tips you have used or if there is interest in exploring the category data type, feel free to comment below.

Введение

Alexander Podrabinovich

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

Первые шаги

Для начала, скачаем набор данных, который будем использовать в работе с Pandas. Данные доступны по ссылке https://github.com/PacktPublishing/Pandas-Cookbook/tree/master/data

Работать будем в Jupiter Notebook. Если ставили его в комплекте с Anaconda, то, скорее всего, путь к исходникам, с которыми работает Jupiter Notebook будет вида: C:/Users/your_user_name/ — можно создать там какую-нибудь папку, сохранить data из ссылки выше, распаковать и, вернувшись в Notebook создать новый документ для работы.

Для подгрузки данных из CSV в DataFrame (DF) используется метод read_csv. Можно загружать CSV через дефолтный модули Python — csv, но read_csv намного быстрее и эффективнее справляется с поставленной задачей.

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

В данном примере мы используем movie.csv из набора данных с github-а.

axis = 0 — т.е. ось 0 — олицетворяет данные, сгруппированные вертикально, используя столбцы. А axis = 1, ось 1 — данные, сгруппированные горизонтально, используя элементы индекса.

В метод head можно передавать число строк, которое хотим увидеть, при выводе. Например, movie.head(7) выведет первые 7 строк DF, по аналогии — movie.tail(7) — выведет последние 7 строк.

В общем и целом, DF стоит на “трех китах”:

  • индексы
  • столбцы
  • данные

К каждому вышеописанному компоненту можно обратиться непосредственно из DF. Каждый компонент — обособленный Python объект со своими методами и свойствами. Зачастую, операции производятся непосредственно над этими компонентами, а не над DF в целом.

Типы данных

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

Чтобы точно узнать, какой тип данных используется в каждом из столбце необходимо написать: move.dtypes — в результате мы получим объект, свойствами которого являются наименования столбцов DF, а значениями — соответствующие типы данных.

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

Выборка единственного столбца или работа с Series

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

Слева у нас индексы, справа — значения. Name: country — наименование объекта типа Series. dtype: object — указывает, какого типа данные хранятся в данном столбце.

Существует возможность превратить объект типа Series в DF, вызвав метод to_frame(): country.to_frame() . В качестве имени столбца Pandas возьмет наименование объекта Series:

Series — методы и свойства

И Series, и DF — имеют очень много свойств и методов. Причем, множество из них совпадают друг с другом. Рассмотрим наиболее популярные и важные методы работы с объектами типа Series.

  • .head() — по аналогии с DF, мы можем использовать данный метод с Series, чтобы получить первые строки объекта
  • .value_counts() — один из наиболее популярных методов для Series с типом данных Object — возвращает количество уникальных записей в столбце. Таким образом, вызвав country.value_counts() получим следующий результат:
  • Метод value_counts может получить параметр normalize=True и вернуть нормализованные данные — country.value_counts(normalize=True):
  • Для того, чтобы подсчитать количество элементов в Series, можно использовать один из трех доступных параметров: country.size (вернет int), country.shape (вернет tuple) и len(country) (вернет int).
    Есть еще и метод country.count() , который, несмотря на свое название, возвращает не количество элементов в Series, а количество НЕ пустых элементов.
  • “Подбить” базовую статистику по Series можно используя следующие доступные методы: min, max, mean, median, std и sum.
    А можно просто вызвать метод describe, который вернет новый Series с индексами в виде наименований различной статистики объекта (min, max, mean и пр) и с их соответствующими значениями. Причем, следует иметь ввиду, что describe() для Series с типом данных Object и для Series с типом данных, к примеру, Float, вернет различную статистику:
  • country.isnull() — вернет Series с типом bool, в котором True будут те элементы, которые НЕ заданы в исходном объекте типа Series.
  • country.notnull() — вернет Series с типом bool, в котором True будут те элементы, которые заданы в исходной объекте типа Series, т.е. не являются нулевыми.
  • country.fillna(‘Not available’) — заполняет переданным значением все нулевые объекты у Series.
  • country.dropna() — вернет Series с удаленными нулевыми значениями.
  • если у нас стоит задача просто узнать, есть ли в Series нулевые значения, то мы можем использовать свойство: country.hasnans — в ответ получим True/False.

Series — операторы

Как Series, так и DF в Pandas работают с большинство операций из Python. Рассмотрим основные операторы, возвращающие новые объекты типа Series с новыми значениями:

  • imdb = movie[‘imdb_score’]
    imdb + 1
    Вернет нам Series со оценками IMDB, увеличенными на 1:
  • По аналогии с плюсом, мы можем использовать и другие арифметические операции с Series: -, *, **, /, //, %.
  • С Series мы можем также использовать любой оператор сравнения: >, <, >=, <=, !=, ==. В результате вернется Series с типом данных bool, где значениями будут True/False в зависимости от поставленного условия.

Все операторы, описанные выше, применяются к каждому элементу Series. В Python нам бы пришлось организовывать for loop, чтобы обойти каждый элемент, Pandas же опирается на NumPy библиотеку, которая предоставляет возможности как для векторизированных вычислений, так и для проведения операция над всей последовательностью данных разом, без использования циклических конструкций. Результатом всех вышеописанных операторов будет новый объект типа Series с такими же индексами как у исходного, но со значениями, соответствующими результату работы оператора.

Pandas всем вышеописанным операторам предоставляет методы-аналогии, которые описаны в таблице ниже:

В Pandas большое количество методов возвращают новые Series или DF, поэтому Pandas прекрасно дружит с таким понятием как chaining method, используя dot-нотацию. Method chaining удобно применять, когда над одним объектом требуется совершить сразу множество тех или иных действий (при условии, что каждое действие — читай: метод, возвращает Series или DF, пригодный для вызова следующего метода). Предположим, мы хотим вывести первые 3 строчки результата метода value_counts:

Еще один хороший пример method chaining — подсчитать количество нулевых элементов в Series. Как мы помним, isnull() возвращает серию, где нулевые элементы представлены как True, а все прочие как False. При вызове метода sum(), Pandas преобразует True/False в 1/0 и вернет корректное число.

Создание понятных индексов

Индекс в DF представляет label для каждой из строк. Если для DF индекс не задан принудительно, то для индексирования Pandas по умолчанию использует RageIndex, который присвоит строкам DF label-ы в виде чисел от 0 до n-1, где n — количество строк в DF.

Мы можем присвоить индексу DF любое его поле. Делается это с помощью метода set_index() следующим образом:

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

Оба вышеописанных метода установки индекса по умолчанию удаляют столбец с изначальным индексом DF, поэтому, если есть необходимость изначальный столбец с индексом, то необходимо использовать метод set_index с параметром drop=False.

Если есть необходимо сбросить ранее установленный индекс, то можно использовать метод reset_index, который поставит ранее установленный индекс на место первого столбца DF, а индексом сделает штатный RageIndex.

Переименование строк и столбцов

Предположим, что в movie у нас лежит DF с индексом в виде movie_title столбца.

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

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

Добавление и удаление столбцов

Pandas предоставляет несколько вариантов добавления новых столбцов в DF. Самым простым способом добавить новый столбец — присвоить ему некое значение. Например, так:

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

При создании новых столбцов, основанных на данных из других, при проведении арифметических операций (например, как в примере выше) Pandas будет автоматически заменять пустые ячейки на 0. Но, если вся строка значений пустая, то и значение в ячейке нового столбца будет пустотой. Убедимся в этом:

Т.е. для 122 фильмов все значения полей с FB лайками были пустыми в исходном DF.

Чтобы удалить столбец, необходимо воспользоваться методом drop():

Существует еще один способ добавления столбцов — метод insert(). Метод принимает три параметра: первый — на какое место в DF должен быть вставлен новый столбец, второй — наименование нового столбца, третий — его значения. Приведем пример. В нашем DF есть столбцы gross и budget, добавим новый столбец profit сразу после gross, который будет равняться разнице между gross и budget. Для этого мы сначала найдем индекс столбца gross с помощью метода get_loc().

Важно заметить, что insert() не возвращает новый DF, а проводит изменения на месте, поэтому присваиваний никаких дополнительных мы не делаем.

how to check the dtype of a column in python pandas

I need to use different functions to treat numeric columns and string columns. What I am doing now is really dumb:

Is there a more elegant way to do this? E.g.

James Bond's user avatar

6 Answers 6

You can access the data-type of a column with dtype :

user2314737's user avatar

David Robinson's user avatar

In pandas 0.20.2 you can do:

So your code becomes:

danthelion's user avatar

I know this is a bit of an old thread but with pandas 19.02, you can do:

Asked question title is general, but authors use case stated in the body of the question is specific. So any other answers may be used.

But in order to fully answer the title question it should be clarified that it seems like all of the approaches may fail in some cases and require some rework. I reviewed all of them (and some additional) in decreasing of reliability order (in my opinion):

1. Comparing types directly via == (accepted answer).

Despite the fact that this is accepted answer and has most upvotes count, I think this method should not be used at all. Because in fact this approach is discouraged in python as mentioned several times here.
But if one still want to use it — should be aware of some pandas-specific dtypes like pd.CategoricalDType , pd.PeriodDtype , or pd.IntervalDtype . Here one have to use extra type( ) in order to recognize dtype correctly:

Another caveat here is that type should be pointed out precisely:

2. isinstance() approach.

This method has not been mentioned in answers so far.

So if direct comparing of types is not a good idea — lets try built-in python function for this purpose, namely — isinstance() .
It fails just in the beginning, because assumes that we have some objects, but pd.Series or pd.DataFrame may be used as just empty containers with predefined dtype but no objects in it:

But if one somehow overcome this issue, and wants to access each object, for example, in the first row and checks its dtype like something like that:

It will be misleading in the case of mixed type of data in single column:

And last but not least — this method cannot directly recognize Category dtype. As stated in docs:

Returning a single item from categorical data will also return the value, not a categorical of length “1”.

So this method is also almost inapplicable.

3. df.dtype.kind approach.

This method yet may work with empty pd.Series or pd.DataFrames but has another problems.

First — it is unable to differ some dtypes:

Second, what is actually still unclear for me, it even returns on some dtypes None.

4. df.select_dtypes approach.

This is almost what we want. This method designed inside pandas so it handles most corner cases mentioned earlier — empty DataFrames, differs numpy or pandas-specific dtypes well. It works well with single dtype like .select_dtypes(‘bool’) . It may be used even for selecting groups of columns based on dtype:

Like so, as stated in the docs:

On may think that here we see first unexpected (at used to be for me: question) results — TimeDelta is included into output DataFrame . But as answered in contrary it should be so, but one have to be aware of it. Note that bool dtype is skipped, that may be also undesired for someone, but it’s due to bool and number are in different «subtrees» of numpy dtypes. In case with bool, we may use test.select_dtypes([‘bool’]) here.

Next restriction of this method is that for current version of pandas (0.24.2), this code: test.select_dtypes(‘period’) will raise NotImplementedError .

And another thing is that it’s unable to differ strings from other objects:

But this is, first — already mentioned in the docs. And second — is not the problem of this method, rather the way strings are stored in DataFrame . But anyway this case have to have some post processing.

5. df.api.types.is_XXX_dtype approach.

This one is intended to be most robust and native way to achieve dtype recognition (path of the module where functions resides says by itself) as i suppose. And it works almost perfectly, but still have at least one caveat and still have to somehow distinguish string columns.

Besides, this may be subjective, but this approach also has more ‘human-understandable’ number dtypes group processing comparing with .select_dtypes(‘number’) :

No timedelta and bool is included. Perfect.

My pipeline exploits exactly this functionality at this moment of time, plus a bit of post hand processing.

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

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