До панд 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')
Починаючи з pandas 1.0, використовуючи натомість "string"
тип .
# pandas >= 1.0
s = pd.Series(['a', 'b', 'c'], dtype="string")
s.dtype
# StringDtype
Ось чому, як цитують документи:
Ви можете випадково зберегти суміш рядків і не рядків в масиві типових об'єктів. Краще мати виділений тип.
object
dtype розбиває конкретні операції типу DataFrame.select_dtypes()
. Не існує чіткого способу вибору просто тексту, виключаючи нетекстові, але все-таки стовпці з типом об'єкта.
Під час читання коду вміст object
масиву dtype менш зрозуміло, ніж 'string'
.
Дивіться також розділ про поведінкові відмінності між "string"
таobject
.
Типи розширень (введені в 0,24 та формалізовані в 1,0) ближче до панд, ніж numpy, що добре, тому що типи numpy недостатньо потужні. Наприклад, NumPy не має жодного способу подання відсутніх даних у цілих даних (з тих пір type(NaN) == float
). Але панди можуть використовувати стовпці Nullable Integer .
Чому я повинен припинити його використання?
Випадкове змішування типів
Перша причина, зазначена в документах, полягає в тому, що ви можете випадково зберігати нетекстові дані в стовпцях об'єктів.
# 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 практично не було можливості відрізнити те, що "A" та "B" не мають одного типу даних.
# 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
З панд 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)
досить гарних причин.