Datawhale开源学习内容链接:https://datawhalechina.github.io/joyful-pandas/build/html/%E7%9B%AE%E5%BD%95/ch8.html
第8章 文本数据
对一个序列进行文本处理,首先需要获取其str对象。
8.2.2 元字符基础
8.2.3 简写字符集
练习题1: 房屋数据集
1、将year列改为整数年份存储。
【我的解答】:
只需保留前4位数字,将该列的值的后两个字去掉即可。
df.year = df.year.str[:-2]
参考答案:
df.year = pd.to_numeric(df.year.str[:-2], errors='ignore').astype('Int64')
df
2、将floor列替换为Level,Highest两列,其中的元素分别为string类型的层类别和整数类型的最高层数。
【我的解答】:
先利用正则表达式来将两个值取出来。观察数据“高层(共6层)”
,我们可以发现,我们可以以「层」
来作为分割标志。
re.findall('.\层', df.floor[0])
输出:
['高层', '6层']
现在我们怎么让re.findall()
对整个列的值进行操作呢?因为它接收的参数有要求。TypeError: expected string or bytes-like object
以上方法好像行不通,得换个思路。从教程上我们可以看到,我们可以使用str.extract
来「提取」相应的字符串。
将floor
中的内容提取出来:
pat = '(\w层)(共(\d+)层)'
s = df.floor.str.extract(pat).rename(columns={0:'Level', 1:'Highest'})
s
将两张表左右连接起来:
pd.concat([df.drop(columns=['floor']), s], axis=1)
3、计算房屋每平米的均价avg_price,以***元/平米的格式存储到表中,其中***为整数。
新建一个表
dff = df.copy()
dff.price = pd.to_numeric(dff.price.str[:-1], errors='ignore')
dff.area = pd.to_numeric(dff.area.str[:-1], errors='ignore')
计算房价:
dff['avg_price'] = dff.apply(lambda x: int((x['price'] / x['area'])*10000), axis=1)
dff
将原表和备份表的房价列进行连接:
pd.concat([df,dff['avg_price']],1)
问题又出来了。。。除了循环遍历该列加入字符串“元/平米”,我不知道还有什么方法。
参考答案:
s_area = pd.to_numeric(df.area.str[:-1])
s_price = pd.to_numeric(df.price.str[:-1])
df['avg_price'] = ((s_price/s_area)*10000).astype('int').astype('string') + '元/平米'
厉害了!这才是把本章知识用起来的节奏~
练习2: 《权力的游戏》剧本数据集
1、计算每一个Episode的台词条数。
注意:由于列名当中存在空格,所以需要先把空格处理掉。
df = pd.read_csv('joyful-pandas-master/data/script.csv')
df.columns = df.columns.str.strip()
df.groupby(['Season','Episode'])['Sentence'].count()
2、以空格为单词的分割符号,请求出单句台词平均单词量最多的前5个人。
将一句台词里面单词的数量单独作为一列:
df['len_words'] = df.apply(lambda x: len(x['Sentence'].split(' ')), axis=1)
df
将单词数量进行排序:
df.sort_values('len_words',ascending=False).head(5)
3、若某人的台词中含有问号,那么下一个说台词的人即为回答者。若上一人台词中含有n个问号,则认为回答者回答了n个问题,请求出回答最多问题的前五人。
将台词单独取出来做处理:
s = pd.Series(df.Sentence.values, index=df.Name.shift(-1))
计算每句台词里面问号的数量,利用名字来分组并加和总数进行排序:
s.str.count('\?').groupby('Name').sum().sort_values(ascending=False).head()