До pandas 1.0 (ну, на самом деле, 0.25) это был дефактный способ объявления серии / столбца в виде строки:
# pandas <= 0.25
# Note to pedants: specifying the type is unnecessary since pandas will
# automagically infer the type as object
s = pd.Series(['a', 'b', 'c'], dtype=str)
s.dtype
# dtype('O')
Начиная с версии 1.0, рассмотрите возможность использования "string"
типа .
# pandas >= 1.0
s = pd.Series(['a', 'b', 'c'], dtype="string")
s.dtype
# StringDtype
Вот почему, как цитируют документы:
Вы можете случайно сохранить смесь строк и не-строк в массиве dtype объекта. Лучше иметь выделенный dtype.
object
dtype прерывает специфичные для dtype операции, такие как DataFrame.select_dtypes()
. Не существует четкого способа выделить только текст, исключая нетекстовые, но все еще столбцы типа объекта.
При чтении кода содержимое object
массива dtype менее понятно, чем 'string'
.
Смотрите также раздел о поведенческих различиях между "string"
иobject
.
Типы расширений (введенные в 0.24 и формализованные в 1.0) ближе к пандам, чем numpy, что хорошо, потому что numpy типы недостаточно мощны. Например, NumPy не имеет никакого способа представления отсутствующих данных в целочисленных данных (поскольку type(NaN) == float
). Но панды могут использовать Nullable Integer столбцы .
Почему я должен прекратить его использовать?
Случайное смешивание dtypes
. Первая причина, как указано в документации, заключается в том, что вы можете случайно сохранить нетекстовые данные в столбцах объекта.
# pandas <= 0.25
pd.Series(['a', 'b', 1.23]) # whoops, this should have been "1.23"
0 a
1 b
2 1.23
dtype: object
pd.Series(['a', 'b', 1.23]).tolist()
# ['a', 'b', 1.23] # oops, pandas was storing this as float all the time.
# pandas >= 1.0
pd.Series(['a', 'b', 1.23], dtype="string")
0 a
1 b
2 1.23
dtype: string
pd.Series(['a', 'b', 1.23], dtype="string").tolist()
# ['a', 'b', '1.23'] # it's a string and we just averted some potentially nasty bugs.
Сложность в различении строк и других объектов Python
Другой очевидный пример - сложнее различить «строки» и «объекты». Объекты по сути являются типом бланкет для любого типа, который не поддерживает векторизованные операции.
Рассматривать,
# Setup
df = pd.DataFrame({'A': ['a', 'b', 'c'], 'B': [{}, [1, 2, 3], 123]})
df
A B
0 a {}
1 b [1, 2, 3]
2 c 123
До панд 0,25 практически не было возможности различить, что «А» и «В» не имеют данных одного типа.
# pandas <= 0.25
df.dtypes
A object
B object
dtype: object
df.select_dtypes(object)
A B
0 a {}
1 b [1, 2, 3]
2 c 123
Начиная с pandas 1.0, это становится намного проще:
# pandas >= 1.0
# Convenience function I call to help illustrate my point.
df = df.convert_dtypes()
df.dtypes
A string
B object
dtype: object
df.select_dtypes("string")
A
0 a
1 b
2 c
Читаемость
Это говорит само за себя ;-)
Хорошо, я должен прекратить использовать это прямо сейчас?
... Нет. На момент написания этого ответа (версия 1.1) преимуществ производительности не было, но в документах ожидается, что будущие усовершенствования значительно повысят производительность и уменьшат использование памяти для "string"
столбцов, а не для объектов. С учетом сказанного, однако, никогда не рано формировать хорошие привычки!
astype("string")
а неastype(str)
по каким-то довольно веским причинам, взгляните.