Pandas(四)

Pandas 学习系列(四)

数据处理兼容性

1
2
3
# 导入相关库
import numpy as np
import pandas as pd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
age city sex birth
name
Tom 18.0 Bei Jing None 2000-02-10
Bob 30.0 Shang Hai male 1988-10-17
Mary NaN Guang Zhou female NaT
James 40.0 Shen Zhen male 1978-08-08
Andy NaN NaN NaN NaT
Alice 30.0 unknown 1988-10-17

之前说过,如果要处理 Series 中的每一个元素,我们可以使用 mapapply 方法:

1
2
# 将所有城市都转成小写
user_info.city.map(lambda x: x.lower())
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-3-a124a99b1001> in <module>
      1 # 将所有城市都转成小写
----> 2 user_info.city.map(lambda x: x.lower())


~/.pyenv/versions/3.6.3/envs/Note/lib/python3.6/site-packages/pandas/core/series.py in map(self, arg, na_action)
   2996         """
   2997         new_values = super(Series, self)._map_values(
-> 2998             arg, na_action=na_action)
   2999         return self._constructor(new_values,
   3000                                  index=self.index).__finalize__(self)


~/.pyenv/versions/3.6.3/envs/Note/lib/python3.6/site-packages/pandas/core/base.py in _map_values(self, mapper, na_action)
   1002 
   1003         # mapper is a function
-> 1004         new_values = map_f(values, mapper)
   1005 
   1006         return new_values


pandas/_libs/src/inference.pyx in pandas._libs.lib.map_infer()


<ipython-input-3-a124a99b1001> in <lambda>(x)
      1 # 将所有城市都转成小写
----> 2 user_info.city.map(lambda x: x.lower())


AttributeError: 'float' object has no attribute 'lower'

居然报错了,那是因为 np.nan 属于 float 类型。

这时候 str 属性的作用就凸显出来了:

1
2
# 还是转换成小写
user_info.city.str.lower()
name
Tom       bei jing 
Bob      shang hai 
Mary     guang zhou
James     shen zhen
Andy            NaN
Alice              
Name: city, dtype: object

这样,做处理的时候,如果一个数据不属于字符串就不会被处理了。

替换和分割

1
user_info.city.str.split(' ')
name
Tom       [Bei, Jing, ]
Bob      [Shang, Hai, ]
Mary      [Guang, Zhou]
James      [Shen, Zhen]
Andy                NaN
Alice              [, ]
Name: city, dtype: object

分割列表中的元素可以使用 get[] 进行访问:

1
user_info.city.str.split(' ').str.get(1)
name
Tom      Jing
Bob       Hai
Mary     Zhou
James    Zhen
Andy      NaN
Alice        
Name: city, dtype: object
1
user_info.city.str.split(' ').str.get(3)
name
Tom     NaN
Bob     NaN
Mary    NaN
James   NaN
Andy    NaN
Alice   NaN
Name: city, dtype: float64
1
user_info.city.str.split(' ').str[1]
name
Tom      Jing
Bob       Hai
Mary     Zhou
James    Zhen
Andy      NaN
Alice        
Name: city, dtype: object

split() 方法有个参数很有意思,expand=True 可以把返回的列表数据以 DataFrame 形式返回:

1
user_info.city.str.split(' ', expand=True)
0 1 2
name
Tom Bei Jing
Mary Guang Zhou None
James Shen Zhen None
Andy NaN NaN NaN
Alice None

提取子字符串

extract() 方法接收一个正则表达式。

1
2
# 匹配空字符串前面的所有字母
user_info.city.str.extract(r'(\w+)\s+', expand=True)
0
name
Tom Bei
Bob Shang
Mary Guang
James Shen
Andy NaN
Alice NaN
1
2
# 匹配空格前后的字符串
user_info.city.str.extract(r'(\w+)\s+(\w+)', expand=True)
0 1
name
Tom Bei Jing
Bob Shang Hai
Mary Guang Zhou
James Shen Zhen
Andy NaN NaN
Alice NaN NaN

extract() 只能返回匹配的第一个元素,extractall() 则会返回所有的匹配元素:

1
user_info.city.str.extractall(r'(\w+)')
0
name match
Tom 0 Bei
1 Jing
Bob 0 Shang
1 Hai
Mary 0 Guang
1 Zhou
James 0 Shen
1 Zhen
1
user_info.city.str.extractall(r'(\w+)\s+')
0
name match
Tom 0 Bei
1 Jing
Bob 0 Shang
1 Hai
Mary 0 Guang
James 0 Shen

最后列举一下 str 所支持常用方法:

方法 描述
cat() 连接字符串
split() 在分隔符上分割字符串
rsplit() 从字符串末尾开始分隔字符串
get() 索引到每个元素(检索第i个元素)
join() 使用分隔符在系列的每个元素中加入字符串
get_dummies() 在分隔符上分割字符串,返回虚拟变量的DataFrame
contains() 如果每个字符串都包含pattern / regex,则返回布尔数组
replace() 用其他字符串替换pattern / regex的出现
repeat() 重复值(s.str.repeat(3)等同于x * 3 t2 >)
pad() 将空格添加到字符串的左侧,右侧或两侧
center() 相当于str.center
ljust() 相当于str.ljust
rjust() 相当于str.rjust
zfill() 等同于str.zfill
wrap() 将长长的字符串拆分为长度小于给定宽度的行
slice() 切分Series中的每个字符串
slice_replace() 用传递的值替换每个字符串中的切片
count() 计数模式的发生
startswith() 相当于每个元素的str.startswith(pat)
endswith() 相当于每个元素的str.endswith(pat)
findall() 计算每个字符串的所有模式/正则表达式的列表
match() 在每个元素上调用re.match,返回匹配的组作为列表
extract() 在每个元素上调用re.search,为每个元素返回一行DataFrame,为每个正则表达式捕获组返回一列
extractall() 在每个元素上调用re.findall,为每个匹配返回一行DataFrame,为每个正则表达式捕获组返回一列
len() 计算字符串长度
strip() 相当于str.strip
rstrip() 相当于str.rstrip
lstrip() 相当于str.lstrip
partition() 等同于str.partition
rpartition() 等同于str.rpartition
lower() 相当于str.lower
upper() 相当于str.upper
find() 相当于str.find
rfind() 相当于str.rfind
index() 相当于str.index
rindex() 相当于str.rindex
capitalize() 相当于str.capitalize
swapcase() 相当于str.swapcase
normalize() 返回Unicode标准格式。相当于unicodedata.normalize
translate() 等同于str.translate
isalnum() 等同于str.isalnum
isalpha() 等同于str.isalpha
isdigit() 相当于str.isdigit
isspace() 等同于str.isspace
islower() 相当于str.islower
isupper() 相当于str.isupper
istitle() 相当于str.istitle
isnumeric() 相当于str.isnumeric
isdecimal() 相当于str.isdecimal