先初始化数据
import pandas as pd import numpy as np index = pd.Index(data=["Tom", "Bob", "Mary", "James", "Andy", "Alice"], name="name") data = { "age": [18, 30, np.nan, 40, np.nan, 30], "city": ["Bei Jing", "Shang Hai", "Guang Zhou", "Shen Zhen", np.nan, " "], "sex": [None, "male", "female", "male", np.nan, "unknown"], "birth": ["2000-02-10", "1988-10-17", None, "1978-08-08", np.nan, "1988-10-17"] } user_info = pd.DataFrame(data=data, index=index)user_info["birth"] = pd.to_datetime(user_info.birth) user_info
为什么要用str属性
文本数据也就是我们常说的字符串,Pandas 为 Series 提供了 str 属性,通过它可以方便的对每个元素进行操作。在之前已经了解过,在对 Series 中每个元素处理时,我们可以使用 map 或 apply 方法。
# 将每个城市都转为小写: user_info.city.map(lambda x: x.lower())
What?竟然出错了,错误原因是因为 float 类型的对象没有 lower 属性。这是因为缺失值 (np.nan)属于float 类型
这时候我们的 str 属性操作来了,来看看如何使用吧
# 将文本转为小写 user_info.city.str.lower() # 统计每个字符串的长度 user_info.city.str.len()
替换和分割
替换操作
# 将空字符串替换成下划线: user_info.city.str.replace(" ", "_") # 使用正则表达式将所有开头为 S 的城市替换为空字符串: user_info.city.str.replace("^S.*", " ")
分割操作
# 根据空字符串来分割某一列: user_info.city.str.split(" ") """ name Tom [BeiJing] Bob [ShangHai] Mary [GuangZhou] James [ShenZhen] Andy NaN Alice [, ] Name: city, dtype: object """ #分割列表中的元素可以使用 get 或 [] 符号进行访问: user_info.city.str.split(" ").str.get(0) """ name Tom BeiJing Bob ShangHai Mary GuangZhou James ShenZhen Andy NaN Alice Name: city, dtype: object """ user_info.city.str.split(" ").str[1] """ name Tom NaN Bob NaN Mary NaN James NaN Andy NaN Alice Name: city, dtype: object """ # 设置参数 expand=True 可以轻松扩展此项以返回 DataFrame user_info.city.str.split(" ", expand=True) """ 0 1 name Tom BeiJing None Bob ShangHai None Mary GuangZhou None James ShenZhen None Andy NaN NaN Alice """
提取子串
从一个长的字符串中提取出子串。
提取第一个匹配的空字符串前面的所有的字母
user_info.city.str.extract("(\w+)\s+", expand=True)
extract 只能够匹配出第一个子串,extract 方法接受一个正则表达式并至少包含一个捕获组,指定参数 expand=True 可以保证每次都返回 DataFrame。
# 匹配空字符串前面的所有的字母 user_info.city.str.extract("(\w+)\s+", expand=True) # 匹配出空字符串前面和后面的所有字母
\s+ :一个或多个空字符串
(\w+):分组捕获任意多个字符
(\w+)\s+:在一个或多个空字符串前,分组捕获任意多个字符
提取第一个匹配的空字符串前面和后面的所有字母
user_info.city.str.extract("(\w+)\s+(\w+)", expand=True)
如果使用多个组提取正则表达式会返回一个 DataFrame,每个组只有一列。
使用 extractall 匹配出所有的子串
将所有组的空白字符串前面的字母都匹配出来
user_info.city.str.extractall("(\w+)\s+")
测试是否包含子串
使用 contains 来测试是否包含子串。
测试城市是否包含子串 “Zh”:
user_info.city.str.contains("Zh")
测试是否是以字母 “S” 开头:
user_info.city.str.contains("^S")
方法摘要