Как работать с текстовыми данными?¶
In [1]: import pandas as pd
- Данные о Титанике
В этом руководстве используется набор данных Titanic, сохраненный в формате CSV. Данные состоят из следующих столбцов:
PassengerId: Идентификатор каждого пассажира.
Survived: Имеет значения 0 и 1. 0 для не выживших и 1 для выживших.
Pclass: Существует 3 класса: класс 1, класс 2 и класс 3.
Name: Имя пассажира.
Sex: Пол пассажира.
Age: Возраст пассажира.
SibSp: Указание на то, что у пассажира есть братья, сестры и супруг.
Parch: Пассажир один или с семьей.
Ticket: Номер билета пассажира.
Fare: Указание тарифа.
Cabin: Каюта пассажира.
Embarked: Категория причала.
In [2]: titanic = pd.read_csv("data/titanic.csv") In [3]: titanic.head() Out[3]: PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S [5 rows x 12 columns]
Сделать все символы в имени строчными.
In [4]: titanic["Name"].str.lower() Out[4]: 0 braund, mr. owen harris 1 cumings, mrs. john bradley (florence briggs th... 2 heikkinen, miss. laina 3 futrelle, mrs. jacques heath (lily may peel) 4 allen, mr. william henry ... 886 montvila, rev. juozas 887 graham, miss. margaret edith 888 johnston, miss. catherine helen "carrie" 889 behr, mr. karl howell 890 dooley, mr. patrick Name: Name, Length: 891, dtype: object
Чтобы преобразовать все строки в столбце
Name
в нижний регистр, выберите столбецName
(см. урок по подмножествам), добавьте метод доступаstr
и примените методlower
. Таким образом, каждая из строк вName
поэлементно преобразуется в нижний регистр.
Подобно методу доступа dt
к объектам даты и времени, метод доступа str
предоставляет доступ к ряду специализированных строковых методов. В целом имена этих методов совпадают с аналогичными встроенными строковыми методами для отдельных элементов, но применяются поэлементно для каждого из значений в столбцах (помните про поэлементные вычисления?).
Создать новый столбец
Surname
с фамилиями пассажиров, удалив часть перед запятой.In [5]: titanic["Name"].str.split(",") Out[5]: 0 [Braund, Mr. Owen Harris] 1 [Cumings, Mrs. John Bradley (Florence Briggs ... 2 [Heikkinen, Miss. Laina] 3 [Futrelle, Mrs. Jacques Heath (Lily May Peel)] 4 [Allen, Mr. William Henry] ... 886 [Montvila, Rev. Juozas] 887 [Graham, Miss. Margaret Edith] 888 [Johnston, Miss. Catherine Helen "Carrie"] 889 [Behr, Mr. Karl Howell] 890 [Dooley, Mr. Patrick] Name: Name, Length: 891, dtype: object
При использовании метода
Series.str.split()
каждое из значений возвращается в виде списка из 2 элементов. Первый элемент — это часть до запятой, а второй элемент — это часть после запятой.In [6]: titanic["Surname"] = titanic["Name"].str.split(",").str.get(0) In [7]: titanic["Surname"] Out[7]: 0 Braund 1 Cumings 2 Heikkinen 3 Futrelle 4 Allen ... 886 Montvila 887 Graham 888 Johnston 889 Behr 890 Dooley Name: Surname, Length: 891, dtype: object
Поскольку нас интересует только первая часть, содержащая фамилию (элемент 0), мы снова можем использовать метод доступа
str
и применитьSeries.str.get()
, чтобы извлечь соответствующую часть. Да, строковые функции можно даже объединять для выполнения нескольких функций за раз!
Более подробная информация об извлечении частей строк доступна в разделе руководства пользователя о разделении и замене строк.
Извлечь данные о графине на борту Титаника.
In [8]: titanic["Name"].str.contains("Countess") Out[8]: 0 False 1 False 2 False 3 False 4 False ... 886 False 887 False 888 False 889 False 890 False Name: Name, Length: 891, dtype: bool
In [9]: titanic[titanic["Name"].str.contains("Countess")] Out[9]: PassengerId Survived Pclass Name ... Fare Cabin Embarked Surname 759 760 1 1 Rothes, the Countess. of (Lucy Noel Martha Dye... ... 86.5 B77 S Rothes [1 rows x 13 columns]
(Интересна история графини? См. Википедию!)
Строковый метод
Series.str.contains()
проверяет каждое из значений в столбцеName
на наличие подстрокиCountess
(графиня), и возвращает для каждого из значенийTrue
(в имени есть подстрокаCountess
) илиFalse
(в имени нет подстрокиCountess
). Этот вывод можно использовать для подвыборки данных с использованием условного (логического) индексирования, введенного в уроке о подмножествах. Поскольку на Титанике была только одна графиня, в результате мы получили один ряд.
Примечание
Доступны и более мощные методы извлечения строк, так как Series.str.contains()
и Series.str.extract()
принимают регулярные выражения, но это выходит за рамки данного руководства.
Более подробная информация об извлечении частей строк доступна в разделе руководства пользователя о сопоставлении и извлечении строк.
У кого из пассажиров Титаника самое длинное имя?
In [10]: titanic["Name"].str.len() Out[10]: 0 23 1 51 2 22 3 44 4 24 .. 886 21 887 28 888 40 889 21 890 19 Name: Name, Length: 891, dtype: int64
Чтобы получить самое длинное имя, мы сначала должны получить длину каждого из имен в столбце
Name
. ФункцияSeries.str.len()
применяется к каждому из имен по отдельности, поэлементно.In [11]: titanic["Name"].str.len().idxmax() Out[11]: 307
Далее нам нужно получить тот ряд (предпочтительно его индексную метку), где длина имени наибольшая. Метод
idxmax()
делает именно это. Это не строковый метод, он применяется к целым числам, поэтомуstr
не используется.In [12]: titanic.loc[titanic["Name"].str.len().idxmax(), "Name"] Out[12]: 'Penasco y Castellana, Mrs. Victor de Satode (Maria Josefa Perez de Soto y Vallejo)'
Основываясь на индексном имени строки (
307
) и столбца (Name
), мы можем сделать выборку с помощью оператораloc
, представленного в уроке о подмножествах.
В столбце «Sex» заменить значения «male» на «M», а «female» на «F».
In [13]: titanic["Sex_short"] = titanic["Sex"].replace({"male": "M", "female": "F"}) In [14]: titanic["Sex_short"] Out[14]: 0 M 1 F 2 F 3 F 4 M .. 886 M 887 F 888 F 889 M 890 M Name: Sex_short, Length: 891, dtype: object
Series.replace()
, не являясь строковым методом, предоставляет удобный способ использования маппингов или словарей для перевода определенных значений. Для маппинга{from : to}
нужен словарь.
Предупреждение
Существует также строковый метод Series.str.replace()
для замены набора символов. Однако при маппинге нескольких значений это будет выглядеть так:
titanic["Sex_short"] = titanic["Sex"].str.replace("female", "F")
titanic["Sex_short"] = titanic["Sex_short"].str.replace("male", "M")
Это громоздко и приводит к ошибкам. Просто подумайте (или попробуйте сами), что произойдет, если эти два выражения применить в обратном порядке!
ЗАПОМНИТЕ
Строковые методы доступны с использованием метода доступа
str
.Строковые методы работают поэлементно, их можно использовать для условного индексирования.
replace
— это удобный метод для преобразования значений в соответствии с заданным словарем.
Полный обзор представлен на страницах руководства пользователя по работе с текстовыми данными.