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. 移除物業費中的元html

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

df['物業費'].map(removeDollar)
複製代碼

eg. 使用匿名函式python

df['物業費'].map(lambda  e: e.split('元')[0])
複製代碼
  • Apply:將函數套用到DataFrame 上的行與列

eg:git

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')github

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),是計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。在不少文本編輯器裏,正則表達式一般被用來檢索、替換那些匹配某個模式的文本。bash

Regular Expression的「Regular」通常被譯爲「正則」、「正規」、「常規」。此處的「Regular」便是「規則」、「規律」的意思,Regular Expression即「描述某種規則的表達式」之意。app

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:ide

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()

複製代碼

通過清理轉換後的數據
相關文章
相關標籤/搜索