Как работать с текстовыми данными?¶
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— это удобный метод для преобразования значений в соответствии с заданным словарем.
Полный обзор представлен на страницах руководства пользователя по работе с текстовыми данными.