In [1]: import pandas as pd
- Titanic data
本教程使用泰坦尼克号数据集,存储为CSV格式。数据包括以下数据列:
PassengerId: 每位乘客的ID。
幸存:乘客是否幸存的指示。
0
表示是,1
表示否。Pclass:三种票等级之一:等级
1
、等级2
和等级3
。姓名:乘客的姓名。
Sex: 乘客的性别。
年龄:乘客的年龄(岁)。
SibSp: 同船的兄弟姐妹或配偶的数量。
Parch: 父母或孩子在船上的数量。
票:乘客的票号。
票价:指示票价。
Cabin: 乘客的舱位号。
Embarked: 登船港。
In [2]: titanic = pd.read_csv("data/titanic.csv") In [3]: titanic.head() Out[3]: PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked 0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S 1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C 2 3 1 3 Heikkinen, Miss Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S 3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S 4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
如何操作文本数据#
将所有名称字符转换为小写。
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
方法。这样,每个字符串都会逐元素转换。
类似于在 时间序列教程 中的 datetime 对象具有 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 Sex Age SibSp Parch Ticket Fare Cabin Embarked Surname 759 760 1 1 Rothes, the Countess. of (Lucy Noel Martha Dye... female 33.0 0 0 110152 86.5 B77 S Rothes
(对她的故事感兴趣吗?请看 Wikipedia!)
字符串方法
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 21 3 44 4 24 .. 886 21 887 27 888 39 889 21 890 19 Name: Name, Length: 891, dtype: int64
要获取最长的名字,我们首先需要获取
Name
列中每个名字的长度。通过使用 pandas 字符串方法,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
虽然
replace()
不是一个字符串方法,但它提供了一种方便的方式,使用映射或词汇表来翻译某些值。它需要一个dictionary
来定义映射{from: to}
。
警告
还有一个 replace()
方法可用于替换特定的字符集。然而,当有一个多个值的映射时,这会变成:
titanic["Sex_short"] = titanic["Sex"].str.replace("female", "F")
titanic["Sex_short"] = titanic["Sex_short"].str.replace("male", "M")
这会变得繁琐且容易出错。只需想象(或亲自尝试)如果这两个声明以相反的顺序应用会发生什么…
REMEMBER
字符串方法可以通过
str
访问器使用。字符串方法逐元素工作,可以用于条件索引。
replace
方法是一个根据给定字典转换值的便捷方法。
在用户指南页面中提供了 处理文本数据 的完整概述。