Python数据科学(七)- 资料清理(Ⅱ)


传送门:

1.资料转换

1.套用向量化计算(例子依然使用我们采集的房天下的数据)

  • 计算新价格
df['总价'] * 1000
  • 使用 Numpy计算新的价格
np.sqrt() 代表开根号

import numpy as np
np.sqrt(df['总价'])
  • 合并两字符串
df['朝向'] + df['户型']
  • 将新计算的均价存入DataFrame
df['均价'] = df['总价'] * 1000 / df['建筑面积']

2.定义函数进行套用

  • map:将函数套用到Series 上的每个元素

eg. 移除物业费中的元

def removeDollar(e):
      return e.split('元')[0]

df['物业费'].map(removeDollar)

eg. 使用匿名函式

df['物业费'].map(lambda  e: e.split('元')[0])
  • Apply:将函数套用到DataFrame 上的行与列

eg:

df = pandas.DataFrame([
                      [60,70,50],\
                      [80,79,68],\
                      [63,66,82]], columns = ['First', 'Second', 'Third']
)
# 以列进行计算
df.apply(lambda e: e.max() - e.min())
# 以行进行计算
df.apply(lambda e: e.max() - e.min(), axis = 1)
  • ApplyMap:将函式套用到DataFrame上的每个元素(elementwise)
    将所有暂无资料的元素替代成缺失值(NaN)
import numpy as np
df.applymap(lambda e :np.nan  if e == '暂无资料' else e)

2.处理时间格式资料

  • 打印出现在的时间
from datetime import datetime 
current_time = datetime.now()
  • 将时间转换成字符串
current_time.strftime('%Y-%m-%d')
  • 将字符串转化为时间
datetime.strptime('2017-04-21', '%Y-%m-%d')
  • 时间回溯
from datetime import timedelta
current_time - timedelta(days = 1)
  • 往前回溯10天(这里的适用场景是想取得过去10天的资讯)
for i in range(1, 10):
        dt = currnet_time - timedelta(days = i)
        print(dt.strftime('%Y-%m-%d'))

注意:这里的时间转换后的格式可以根据需要设定,eg:dt.strftime('%Y/%m/%d')

3.转换UNIX时间,即从1970年1月1日到现在过了多少秒

  • 将datetime转换为UNIX timestamp
from time import mktime
mktime(current_time.timetuple())
  • 将UNIX timestamp 转换为datetime
datetime.fromtimestamp(1492859823)

4.在pandas转换时间

  • 转换前


import pandas
df = pandas.read_excel('data/house_sample.xlsx')
df['张贴日期'] = pandas.to_datetime(df['张贴日期'], format = '西元%Y年%m月%d日')
  • 转换后


3.重塑资料

1.虚拟变量(Dummy Variable)

百度百科:虚拟变量 ( Dummy Variables) 又称虚设变量、名义变量或哑变量,用以反映质的属性的一个人工变量,是量化了的自变量,通常取值为0或1。引入哑变量可使线形回归模型变得更复杂,但对问题描述更简明,一个方程能达到两个方程的作用,而且接近现实。
eg:如下表中的朝向就可以建立一个虚拟变量

  • 建立虚拟变量
pandas.get_dummies(df['朝向'])
  • 合并虚拟变量与原DataFrame
df = pandas.concat([df, pandas.get_dummies(df['朝向'])], axis = 1)
  • 舍弃原有字段
df.drop('朝向', axis = 1)

2.建立透视表(pivot_table)

df2 = df.pivot_table(index = '张贴日期', columns = '产权性质', values = '总价', aggfunc = sum, fill_value = 0) 
# fill_value = 0 指代的是把NaN替换成0
df2.head()
没加fill_value = 0的结果
加过fill_value = 0的结果
df3 = df.pivot_table(index = '产权性质', columns = '张贴日期', values = '总价', aggfunc = sum)
df3.head()


另外,两者进行转换的话也可以直接通过df2.T做转换。

3.长宽表格的转换(stack & unstack)

  • 建立多索引的透视表
df_multi_idx = df.pivot_table(index=['楼层', '装修'],columns='张贴日期', values='总价', aggfunc=sum)
  • 转换为宽表格
df_wide = df_multi_idx.unstack()
df_wide.head()
  • 转换为长表格
df_long = df_wide.stack()
df_long.head()

4.学习正则表达式

1.正则表达式概述

正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

Regular Expression的“Regular”一般被译为“正则”、“正规”、“常规”。此处的“Regular”即是“规则”、“规律”的意思,Regular Expression即“描述某种规则的表达式”之意。

Python通过re模块提供对正则表达式的支持。使用re的一般步骤是先使用re.compile()函数,将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作。

1.正则表达式(Regular Expression):查询和匹配字符串的规则

2.正则表达式表示数据
普通字符: 元数据,可以用于匹配指定的字符
r = “a”:用于在目标字符串中匹配小写字母a元字符
r = “.”:用于匹配任意一个字符
r = “\”:转移字符~用于将一个普通的字符,转义成一个有意义的字符
r = “\d”:表示一个0~9之间的整数
r = “\D”:表示一个非数字字符
r = “\w”:表示任意一个0~9或者字母或者下划线的字符
r = “\W”:表示任意一个特殊字符
r = “\s”:表示匹配一个空白字符
r = “\S”:表示匹配一个非空白字符
r = “^”:匹配字符串的开头位置
r = “$”:匹配字符串的结束位置
r = “\d*”:表示前面匹配的字符出现了0次或者多次
r = “\d?”:表示前面匹配的字符出现了0次或者1次
r =”\d+”:表示前面匹配的字符出现了1次或者多次

#范围匹配
分组匹配方式:将多个匹配字符当成一个完整的匹配公式
(abc):用于在目标字符串中查询abc同时出现的地方 
选择匹配方式:将指定的多个字符,选择其中一个进行匹配
[abc]:用于在目标字符串中,查询a或者b或者c出现的地方
[0-9]:用于匹配一个0~9之间的数字->等价于\d
[a-z]:用于匹配一个a-z之间的字母
[A-Z]:用于匹配一个A-Z之间的字母
[a-zA-Z]:用于匹配一个字母【大小写均可】
[a-zA-Z0-9_]:用于匹配一个非特殊字符,等价于\w

#范围匹配
\d{m, n}:匹配到的字符出现了至少m次,最多n次
\d{,20}:匹配一个数字最多出现20次
\d{8,}:匹配一个数字,最少出现8次
\d{8,16}:匹配一个数字,最少出现8次,最多出现16次

#正则表达式在python中的使用
正则表达式,在python中,主要用到了一个re模块
compile():编译正则表达式
pattern = re.compile(“^\d{2,}$”)
pattern = r‘^\d{2,}$’

pattern.match(str,begin,end):从指定的字符串str第一个字符查询匹配的字符

pattern.search(str, begin, end):从指定的字符串中直接进行查询,查询到的第一个结果作为匹配结果

pattern.findall(str):从指定的字符串中,查询符合匹配规则的字符,将所有符合的字符存放在一个列表中

pattern.finditer(str):从指定的字符串中,查询符合匹配规则的字符保存在一个可以迭代的对象中

pattern.sub():替换
pattern.split():拆分

eg:

import re
email = 'zhiji@github.com'
m = re.match('(\w+)@([a-z\.]+)', email)
or
m = re.match('(\w+)@(.+)', email)
>>>m.group(1)
zhiji
>>>m.group(2)
github.com
>>>m.groups()
('zhiji', 'github.com')

2.在DataFrame上使用正规表达式

  • 从户型用正规表达式抽取室、厅、厨、卫栏位


    未处理的数据
df[['室', '厅', '厨', '卫']] = df['户型'].str.extract('(\d+)室(\d+)厅(\d+)厨(\d+)卫', expand=False)
使用正则处理过的数据

之前写过详细的正则表达式的文章,传送门在这里正则表达式

5.实例处理

我们通过对新浪微博新闻数据的采集和处理作为案例

import requests
import pandas
import re
from bs4 import BeautifulSoup

def get_article(url):
    res1 = requests.get(url)
    res1.encoding = 'utf-8'
    soup1 = BeautifulSoup(res1.text, 'html.parser')
    dic = {}
    dic['title'] = soup1.select('.page-header #artibodyTitle')[0].text
    dic['content'] = ''.join([ele.text for ele in soup1.select('.article_16 p')])
    dic['source'] = soup1.select('#navtimeSource')[0].text
    dic['keyword'] = soup1.select('.article-info .article-keywords')[0].text
    return dic

def get_all_news():
    res = requests.get('http://news.sina.com.cn/china/')
    res.encoding = 'utf-8'
    soup = BeautifulSoup(res.text, 'html.parser')
    newsary = []
    for link in soup.select('.news-item'):
        if len(link.select('h2 a')) > 0:
            newsary.append(get_article(link.select('h2 a')[0]['href']))
    df = pandas.DataFrame(newsary)
    # 进行数据清理
    df['keyword'] = df['keyword'].map(lambda e: e.split(':')[1].split())
    # df['source'] = df['source'].map(lambda e: e.split())
    df[['datetime', 'from']] = df['source'].str.extract('(\d+年\d+月\d+日\d+:\d+)[\t|\n]+?(\w+)', expand=False)
    print(df[['datetime', 'from']])
    # 因为df['datetime']是object格式,为了后期的取值,例:取年df['datetime'].map(lambda e : e.year) 我们需要把格式转换为时间格式
    df['datetime'] = pandas.to_datetime(df['datetime'], format = '%Y年%m月%d日%H:%M')
    del df['source']
    # 对即将保存的格式进行调整
    df = df[['from', 'title', 'content', 'keyword', 'datetime']]
    # 将整理好的数据储存Excel
    df.to_excel('news.xlsx')

if __name__ == '__main__':
    get_all_news()

经过清理转换后的数据
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266