Почему Pandas сообщает мне, что у меня есть объекты, хотя каждый элемент в выбранном столбце является строкой - даже после явного преобразования.
Это мой DataFrame:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 56992 entries, 0 to 56991
Data columns (total 7 columns):
id 56992 non-null values
attr1 56992 non-null values
attr2 56992 non-null values
attr3 56992 non-null values
attr4 56992 non-null values
attr5 56992 non-null values
attr6 56992 non-null values
dtypes: int64(2), object(5)
Их пять dtype object
. Я явно конвертирую эти объекты в строки:
for c in df.columns:
if df[c].dtype == object:
print "convert ", df[c].name, " to string"
df[c] = df[c].astype(str)
Тогда df["attr2"]
все еще есть dtype object
, хотя type(df["attr2"].ix[0]
показывает str
, что это правильно.
Панды различают int64
и float64
и object
. Какая логика за этим, когда нет dtype str
? Почему str
покрыто object
?
Ответы:
Объект dtype происходит от NumPy, он описывает тип элемента в ndarray. Каждый элемент в ndarray должен иметь одинаковый размер в байтах. Для int64 и float64 это 8 байтов. Но для строк длина строки не фиксирована. Поэтому вместо того, чтобы сохранять байты строк в ndarray напрямую, Pandas использует объект ndarray, который сохраняет указатели на объекты, из-за этого dtype этого типа ndarray является объектом.
Вот пример:
источник
Принятый ответ хорош. Просто хотел дать ответ со ссылкой на документацию . В документации говорится:
Как говорится в ведущем комментарии: «Не беспокойтесь об этом, так должно быть». (Хотя принятый ответ отлично объяснил «почему»; строки имеют переменную длину)
источник
astype(str)
хотя я все еще удивляюсь, что преобразование строк необходимоОтвет @ HYRY отличный. Я просто хочу дать немного больше контекста ...
Массивы хранятся данные , как непрерывный , фиксированного размера блоков памяти. Сочетание этих свойств вместе делает массивы молниеносными для доступа к данным. Например, рассмотрим , как ваш компьютер может хранить массив 32-битных целых чисел,
[3,0,1]
.Если вы попросите свой компьютер получить 3-й элемент в массиве, он начнется с начала, а затем перейдет через 64 бита, чтобы перейти к 3-му элементу. Точное знание того, через сколько битов нужно перескочить, делает массивы быстрыми .
Теперь рассмотрим последовательность строк
['hello', 'i', 'am', 'a', 'banana']
. Строки - это объекты, которые различаются по размеру, поэтому, если вы попытаетесь сохранить их в смежных блоках памяти, это будет выглядеть так.Теперь у вашего компьютера нет быстрого доступа к случайно запрошенному элементу. Ключ к преодолению этого - использование указателей. По сути, храните каждую строку в некотором случайном месте памяти и заполняйте массив адресом памяти каждой строки. (Адреса памяти - это просто целые числа.) Теперь все выглядит так:
Теперь, если вы попросите свой компьютер получить 3-й элемент, как и раньше, он может перескочить через 64 бита (при условии, что адреса памяти - 32-битные целые числа), а затем сделать один дополнительный шаг, чтобы получить строку.
Проблема для NumPy заключается в том, что нет гарантии, что указатели действительно указывают на строки. Вот почему он сообщает dtype как «объект».
Без зазрения совести вставлю статью в свой блог, где я изначально это обсуждал.
источник
Начиная с версии 1.0.0 (январь 2020 г.), pandas представлена как экспериментальная функция, обеспечивающая первоклассную поддержку строковых типов через
pandas.StringDtype
.Хотя вы по-прежнему будете видеть
object
по умолчанию, новый тип можно использовать, указавdtype
изpd.StringDtype
или просто'string'
:источник
The implementation may change without warning.
это означает , что новые обновления сломают ваши старые программы.