数据科学

有90%的有用数据,都在数据库中。

数据

数据类型

  1. 定性数据: 叙述特征或种类,例如:种族,区域。
  2. 定量数据: 可以被计数或测量,例如:身高,消费金额。

定量数据

  1. 离散数据
    只能用自然数或整数单位计算。
    只能按计量单位数计数,可由一般计算方法取得。
    例如:班级人数
  2. 连续数据
    一定区间内可以任意取值的数据,其数值是连续不断的,相邻两个数值可以取无限个数值。
    其数值只能用测量或计量的方法取得。
    例如:零件规格尺寸

数据来源

  1. 结构化数据
    每条数据都有固定的字段,固定的格式,方便程序进行后续取用与分析。
    例如:数据库。
  2. 半结构化数据(要使数据具有弹性,能够存储,也能够便利查找。)
    数据介于结构化与非结构化之间,
    数据具有字段,也可以依据字段来查找,使用方便,但每条数据的字段可能不一致。
    例如:XMLJSON
  3. 非结构化数据
    没有固定的格式,必须整理以后才能存取
    例如:格式的文字,网页数据,文件数据。

非结构化数据必须透过ETL(Extract抽取, Transfromation转换, Loading储存)工具将数据转为结构化数据才能取用。

文件处理

普通操作文件

with open('fliename', 'raw') as f:
    f.write('hello world')
    f.read()
    f.readlines()

CSV格式数据

方式一:
通过文件打开读取数据。

with open('./Population.csv', 'r', encoding='UTF-8') as f:
    # print(f.read())
    for line in f.readlines():
        print(line)

方式二:
通过pandas模块读取

import pandas as pd


df = pd.read_csv('./Population.csv')
print(df.values)

Excel格式数据

import pandas as pd

filename = 'house_sample.xlsx'

df = pd.read_excel(filename)

print(df.values[0][0])

JSON格式数据

方式1:
通过文件读取,然后json模块读取,转换为list类型数据。

import json


filename = 'jd.json'
with open(filename, 'r') as f:
    fc = f.read()

df = json.loads(fc)
print(df)

strjson = json.dumps(df)

方式2:
通过pandas模块读取

import pandas as pd

filename = 'jd.json'

df = pd.read_json(filename)

print(df.values)

XML格式数据

通过模块xml处理:

import xml.etree.ElementTree as ET

filename = 'weather.xml'
tree = ET.parse(filename)

root = tree.getroot()

for city in root.iter('city'):
    print(city.get('cityname'))

网络爬虫

需要模块:

  1. BeautifulSoup
  2. request:网络获取,可以使用REST操作POST,PUT,GET,DELETE存取网络资源.

简单爬取:

import requests

newurl = 'http://news.qq.com/'

res = requests.get(newurl)
print(res.text)

BeautifulSoup

bs4模块,可以把抓取的网页变成DOM文档,允许使用CSS选择器来寻找需要的内容。

import requests
from bs4 import BeautifulSoup

newurl = 'http://news.qq.com/'

res = requests.get(newurl)

html = res.text
# print(res.text)

html = '\
    <h1 title="123" id="h">hello world</h1>\
    <h2>数据科学</h2>
'
soup = BeautifulSoup(html, 'html.parser')

s = soup.select('h1') # 获取元素
print(s[0]['title']) # 获取属性

抓取位置实用工具

  1. Chrome
  2. Firefox
  3. InfoLite
  4. xpath lxml

从其它地方获取到数据,存储为.json, .cvs, .xlsx,需要从DataFrame()中获取。

import pandas
import requests
from bs4 import BeautifulSoup

newurl = 'http://news.qq.com/'
html = requests.get(newurl).text

soup = BeautifulSoup(html, 'html.parser')
warp = soup.select('.head .Q-tpWrap .text')

dataArr = []
for news in warp:
    dataArr.append({'name': news.select('a')[0].text.encode(), 'herf': news.select('a')[0]['href']})

newsdf = pandas.DataFrame(dataArr)
newsdf.to_json('news.json')
newsdf.to_csv('news.csv')
newsdf.to_excel('news.xlsx')
import requests
from bs4 import BeautifulSoup
import json

url = 'http://xm.esf.fang.com/'
html = requests.get(url).text

soup = BeautifulSoup(html, 'html.parser')
resultArr = []

for house in soup.select('.shop_list dl'):
    shop = {
        'tit_shop': house.select('dd:nth-of-type(1) .tit_shop') and house.select('dd:nth-of-type(1) .tit_shop')[0].text,
        'tel_shop': house.select('dd:nth-of-type(1) .tel_shop') and ''.join( house.select('dd:nth-of-type(1) .tel_shop')[0].text.split('|') ).strip(),
        'add_shop': house.select('dd:nth-of-type(1) .add_shop') and '小区名字:' + house.select('dd:nth-of-type(1) .add_shop')[0].select('a')[0].text + '; 具体地址:' + house.select('dd:nth-of-type(1) .add_shop')[0].select('span')[0].text,
        'price_shop': house.select('dd:nth-of-type(2) span b') and house.select('dd:nth-of-type(2) span b')[0].text,
        'sqm': house.select('dd:nth-of-type(2) span') and house.select('dd:nth-of-type(2) span')[1].text
    }
    resultArr.append(shop)

resultArr = json.dumps(resultArr)

with open('fang.json', 'w') as f:
    f.write(resultArr)
print('ok')

爬取房天下的厦门二手房数据

import json

import requests
from bs4 import BeautifulSoup

url = 'http://xm.esf.fang.com/'
html = requests.get(url).text
domain = 'http://xm.esf.fang.com'


def getUrlDetails(url):
    dhtml = requests.get(url).text
    dsoup = BeautifulSoup(dhtml, 'html.parser')

    info = {}
    info['标题'] = dsoup.select('.title h1')[0] and dsoup.select(
        '.title h1')[0].text.strip()
    info['总价'] = dsoup.select('.tab-cont-right .price_esf')[0].text

    for item in dsoup.select('.tab-cont-right .trl-item1'):
        info[item.select('.font14')[0].text] = item.select(
            '.tt')[0].text.strip()
    info['地址'] = dsoup.select(
        '.tab-cont-right .trl-item2 .rcont')[0].text.strip()[0:-2]
    for item in dsoup.select('.zf_new_left .cont .text-item'):
        st_split = item.text.strip().split('\n')
        while '' in st_split:
            st_split.remove('')
        while '\r' in st_split:
            st_split.remove('\r')
        if len(st_split) > 2:
            st_split = [st_split[0]] + [''.join(st_split[1:])]
        k, v = st_split
        info[k] = v.strip()
    return info


if __name__ == '__main__':
    soup = BeautifulSoup(html, 'html.parser')
    resultArr = []
    for house in soup.select('.shop_list dl'):
        if house.select('h4 a'):
            resUrl = domain + house.select('h4 a')[0]['href']
            if getUrlDetails(resUrl):
                resultArr.append(getUrlDetails(resUrl))

    result = json.dumps(resultArr)
    print('爬取完毕')
    with open('house.json', 'w') as f:
        f.write(result)
    print('写入完毕')

爬取拉勾网招聘信息 json格式

# coding=utf-8

import json
import time

import requests
import xlwt

url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'

# 获取存储职位信息的json对象,遍历获得公司名、福利待遇、工作地点、学历要求、工作类型、发布时间、职位名称、薪资、工作年限
def getJobRow(url, datas):
    time.sleep(10)
    header = {
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
        'Host': 'www.lagou.com',
        'Origin': 'https://www.lagou.com',
        'Referer': 'https://www.lagou.com/jobs/list_?labelWords=&fromSearch=true&suginput='
    }
    cookie = {
        'Cookie': 'JSESSIONID=ABAAABAAAIAACBI80DD5F5ACDEA0EB9CA0A1B926B8EAD3C; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1539844668; _ga=GA1.2.439735849.1539844668; _gid=GA1.2.491577759.1539844668; user_trace_token=20181018143747-53713f4a-d2a0-11e8-814e-525400f775ce; LGSID=20181018143747-53714082-d2a0-11e8-814e-525400f775ce; PRE_UTM=; PRE_HOST=; PRE_SITE=; PRE_LAND=https%3A%2F%2Fwww.lagou.com%2F; LGUID=20181018143747-53714251-d2a0-11e8-814e-525400f775ce; index_location_city=%E4%B8%8A%E6%B5%B7; TG-TRACK-CODE=index_search; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1539844675; LGRID=20181018143754-57b25578-d2a0-11e8-bdc4-5254005c3644; SEARCH_ID=d0a97cea1d1d47d0afa41b3f298f41d5'
    }
    result_data = requests.post(url=url, cookies=cookie, headers=header, data=datas).json()
    content = result_data['content']['positionResult']['result']

    info_item = []
    for i in content:
        information = []
        information.append(i['positionId']) # 岗位对应ID
        information.append(i['companyFullName']) # 公司全名
        information.append(i['companyLabelList']) # 福利待遇
        information.append(i['district']) # 工作地点
        information.append(i['education']) # 学历要求
        information.append(i['firstType']) # 工作类型
        information.append(i['formatCreateTime']) # 发布时间
        information.append(i['positionName']) # 职位名称
        information.append(i['salary']) # 薪资
        information.append(i['workYear']) # 工作年限

        info_item.append(information)
    return info_item

def main():
    city = input('请输入爬取的城市:')
    page = int(input('请输入爬取的页数:'))
    kd = input('请输入爬取关键词:')
    info_result = []
    title = ['岗位id', '公司全名', '福利待遇', '工作地点', '学历要求', '工作类型', '发布时间', '职位名称', '薪资', '工作年限']
    info_result.append(title)

    for x in range(1, page+1):
        datas = {
            'first': True,
            'pn': x,
            'kd': kd,
            'city': city
        }
        info = getJobRow(url, datas)
        info_result = info_result + info
        print(info_result, 'info_result')

        # 写入excel的数据格式组装成: [[表头数据], [row数据], [row], [row]]
        workbook = xlwt.Workbook(encoding='utf-8')
        worksheet = workbook.add_sheet('lagou' + kd, cell_overwrite_ok=True)

        for i, row in enumerate(info_result):
            # print row
            for j, col in enumerate(row):
                # print col
                worksheet.write(i, j, col) # x,y 位置, col 内容

        workbook.save('lagou' + kd + city + '.xls')

if __name__ == '__main__':
    main()

数据清理

  • 数据处理
  • 资料分析
  • 诠释结果

真正能用在数据分析的时间很少,必须要能够善用工具。

资料分析:

  • 资料筛选
  • 侦测缺失值
  • 补齐缺失值
  • 资料转换
  • 处理时间格式数据
  • 重塑资料
  • 学习正规运算式

pandas处理资料:

  • Table-like格式,
  • 提供高效能,简易使用的数据格式(Data Frame)让用户可以快速操作及分析资料。
  • pandas底层是numpy

numpy特点:

  • python数学运算套件
  • N维数组对象
  • 多种数学运算函数
  • 可整合C/C++Fortran

使用numpy产生结构化信息,有缺陷,而在numpy上完善的pandas,比较合理使用数据。

pandas增加序列Series结构:

  • 类似Array,List的一维物件
  • 每个Series都可以透过其索引进行存取
  • 预设Series会以0到Series长度作为索引编号

数据处理

资料筛选

存取元素与切割:

df.ix[1] # 取一条记录
df.ix[1:4] # 取1~4条记录
df['name'] # 通过字段取数据
df[['name', 'age']] # 通过多个字段取数据,获取每条字段下的数据

df[1:2, ['name', 'age']] # 根据索引号与字段名筛选数据

df['gender'] == 'M' # 根据enum特点的值判断筛选数据,返回True 和 False
df[df['gender'] == 'M'] # 根据enum特点的值判断筛选数据, 整张表中符合的返回

df[(df['gender' == 'M']) & (df['age' >= 30])] # 使用 & 取条件交集
df[(df['gender' == 'M']) | (df['age' >= 30])] # 使用 | 取条件

df['employee'] = True # 新增字段
del df['employee'] # 删除字段
df = df.drop('empyloyee', axis=1) # 删除字段

df.loc[6] = {'age': 18, 'gender': 'F', 'name': 'aa'} # 新增一条记录
df.append(pd.DataFrame([{'age': 18, 'gender': 'F', 'name': 'aa'}]), ignore_index=True) # 新增记录
df = df.drop(6) # 删除某条记录

df['userid'] = range(101, 117) # 设定新的索引
df.set_index('userid', inplace=True) # 设定新索引

df.iloc[1] # 设定新的索引去获取数据
df.iloc[[1:3]] # 设定新的索引去获取数据

获取值的三种方式

df.ix[[101, 102]] # 使用ix取值,useid
df.loc[[101, 105]] # 使用loc取值,useid
df.iloc[1, 2]  # 使用iloc取值,索引

侦测缺失值

  • 数据中有特定或一个范围的值是不完全的
  • 缺失值可能会导致数据分析是产生偏误的推论
  • 缺失值可能来自机械的缺失(机械故障,导致数据无法被完整保存)或是人为的缺失(填写信息不完整或数据真假情况)

占位:
使用numpy中的numpy.nan占位表示缺失值

pd.DataFrame(['a', numpy.nan])

检查序列是否有缺失值:

df['gender'].notnull() # 检查非缺失值数据
df['gender'].isnull() # 检查缺失值数据

检查字段或Data Frame是否含有缺失值:

df.name.isnull().values.any() # 检查字段是否含有缺失值

df.isnull().values.any() # 检查DataFrame是否含有缺失值,返回True或False

计算缺失值数量:

df.isnull().sum() # 检查字段缺失值的数量
df.isnull().sum().sum() # 计算所有缺失值的数量

补齐缺失值

  • 舍弃缺失值:当缺失值占数据比例很低时。
  • 使用平均数,中位数,众数等叙述性统计补齐缺失值。
  • 使用内插法补齐缺失值:如果字段数据呈线性规律。

舍弃缺失值:

df.dropna() # 舍弃含有任意缺失值的行
df.dropna(how='all') # 舍弃所有都含有缺失值的行,每个字段都是NaN
df.dropna(thresh=2) # 舍弃超过两栏缺失值的行

df['age'] = numpy.nan # 增加一列包含缺失值
df.dropna(axis=1, how='all') # 舍弃皆为缺失值的列

填补缺失值:

df.fillna(0) # 用0填补缺失值
df['age'].fillna(df['age'].mean()) # 用平均数填补缺失值
df['age'].fillna(df.groupby('gender')['age'].transfrom('mean')) # 用各性别年龄平均填补缺失值

df.fillna(method='pad') # 向后填充缺失值
df.fillna(method='bfill', limit=2) # 向前填充缺失值

维护处理不需要数据或者特殊的数为np.nan:

df.loc[df['物业费用'] == '暂无资料', '物业费用'] = np.nan # 修改“暂无资料”为"np.nan"

查看前三行数据:df.head(3)
查看后三行数据:df.tail(3)
查看DataFrame信息: df.info()
查看字段名称: df.columns
查看字段类型:df.dtypes
叙述性统计:df.describe()
检查缺失值: df.isnull().any()
缺失值统计: df.isnull().sum()
缺失值在整体数据中的比例:df.isnull().sum() / df.count()
对特殊字段进行筛选处理: df['volume'].value_counts()
缺失值补齐:df['volume'].fillna(0)

资料转换

如何清洗,转换该数据? 使用向量化计算

计算新值:

df['总价'] * 10000 # 计算新价格

使用物件计算新价格:

import numpy as np
np.sqrt(df['总价'])

合并二个字段:

df['朝向'] + df['户型']

计算需要的新值:

df['均价'] = df['总价'] * 1000 / df['建筑面积']

map: 将函数套用到字段(Series)上的每个元素

def removeDollar(e):
  return e.split('万')[0]
df['总价'].map(removeDollar) # 移除“总价”字段中含有的"万"字符

df['总价'].map(lamdba e: e.split('万')[0]) # lamdba的写法

apply: 将函数套用到DataFrame上的行或列

df.apply(lambda e: e.max() - e.min(), axis=1) # axis=0(列)axis=1(行) 根据行还是列

applyMap: 将函数套用到DataFrame上的每个元素

import numpy as np
df.applymap(lamdba e: np.nan if e == '暂无资料' else e) # 将所有暂无资料的元素替代成缺失值(NaN)

'''
lamdba e: np.nan if e == '暂无资料' else e

def convertNaN(e):
    if e == '暂无资料':
        return np.nan
    else:
        return e
'''

处理时间格式

现在时间:

from datetime import datetime
current_time =  datetime.now()

将时间转换成字符串:

current_time.strftime('%Y-%m-%d')

将字符串转为时间:

datetime.strptime('2018-08-17', '%Y-%m-%d')

往前回溯一天:

from datetime import timedelta
current_time - timedelta(day=1)

往前回溯十天:

from datetime import timedelta
for i in range(1, 10):
    dt = current_time - timedelta(days=i)
    print(dt.strftime('%Y-%m-%d')) # 取得多天的日期
    
current_time - timedelta(day=10)    

datetime转换为UNIX timestamp:

from time import mktime
mktime(current_time.timetuple()) # 需转tuple

UNIX timestamp转换为datetime:

datetime.fromtimestamp(1538202783)

pandas转换时间:

import pandas as pd
df['日期'] = pd.to_datetime(df['日期'], format='%Y年%m月%d日') # 默认转换为`-` 2018-9-29

资料重塑

创建虚拟变量:

pandas.get_dummies(df['朝向']) # 建立虚拟变量
df = pandas.concat([df, pandas.get_dummies(df['朝向'])], axis=1) # 合并虚拟变量与原DataFrame,成为数据中的真实数据
df.drop(df['朝向'], axis=1) # 舍弃原有字段

建立透视表pivot_table

df2 = df.pivot_table(index='单价', columns='产权年限', values='参考均价', aggfunc=sum)
df2.head() # index,列名字,columns,字段名,values,函数执行后的数据
# 可以使用 df2.T 可以透视表行列转换

df3 = df.pivot_table(index=['产权性质', '产权年限'], columns='日期', values='总价', aggfunc=sum)
df3.head()

《数据科学》

正则

《数据科学》

把数据通过正则出来。

  • 比对,对比。
  • []
  • *?, +?, ??非贪婪模式(尽可能少的对比)

通过字段名获取捕获到的数据

m = re.match(r'(?P<first_name>\w+) (?P<last_name>\w+)', 'David Chiu')
print(m.group('first_name'), m.group('last_name'))
str1 = 'scp file.text root@10.0.0.1:./'
m = re.search('^scp ([\w\.]+) (\w+)@([\w\.]+):(.+)', str1)
if m:
    print(m.group(1), m.group(2), m.group(3), m.group(4))

DataFrame中使用正则:

df[['室', '厅', '卫']]  = df['户型'].str.extract(r'(\d+)室(\d+)厅(\d+)卫', expand=False)
# 室,厅,卫等信息

爬取新浪新闻:

import pandas as pd
import requests
from bs4 import BeautifulSoup as bs


def getDetails(url, idx):
    if idx > 5:
        return
    print(url, 'url')
    res = requests.get(url)
    res.encoding = 'utf-8'
    d = bs(res.text, 'html.parser')

    title = d.select('.main-title')[0].text
    create_time = d.select('.date-source')[0].select('.date')[0].text
    source = d.select('.date-source')[0].select('.source')[0].text
    article = ' '.join(d.select('#article')[0].text.split())
    keywords = d.select('#keywords')[0].text

    return {
        'title': title,
        'create_time': create_time,
        'source': source,
        'article': article,
        'keywords': keywords
    }


if __name__ == '__main__':
    url = 'https://news.sina.com.cn/china/'
    res = requests.get(url)
    res.encoding = 'utf-8'
    dsoup = bs(res.text, 'html.parser')
    news_herf = [h['href']
                 for h in dsoup.select('.left-content-1 div')[3].select('li a')]
    newArr = []
    resultArr = []
    for idx, new in enumerate(news_herf):
        t = getDetails(new, idx)
        if t:
            newArr.append(t)

    df = pd.DataFrame(newArr)
    df['keywords'] = df['keywords'].apply(lambda i: i.split(':')[1].split())
    df['create_time'] = pd.to_datetime(df['create_time'], format=r'%Y年%m月%d日 %H:%M')
    df = df[['title', 'source', 'create_time', 'keywords', 'article']] # 转换字段顺序
    df.to_json('news.json')

    print('ok')

可视化数据

叙述性统计

有系统的归纳数据,了解数据的轮廓
对数据样本做叙述性,例如:平均数,标准偏差,计次频率,百分比
对数据资料的图像化处理,将数据摘要变为图表
经常更加偏重于叙述性统计处理可视化数据.

  • 多数资料分析,80%在于如何加总与平均
  • 用SQL做叙述性统计,分割数据,转换数据,聚合数据,探索数据。
  • Pyton类似的分析工具

获取股价:pandas-datareader

import pandas_datareader as pdd

df = pdd.DataReader('BABA', data_source='yahoo')
print(df.tail())

简易的统计单个字段:
算出总和:df['volume'].sum()
算出平均:df['volume'].mean()
算出标准差:df['volume'].std()
取得最小值:df['volume'].min()
取得最大值:df['volume'].max()
取得记录数:df['volume'].count()
取得整体叙述性统计: df.describe()

import pandas_datareader as pdd

df = pdd.DataReader('BABA', data_source='yahoo')


# 计算涨跌
df['diff'] = df['Close'] - df['Open']
df['rise'] = df['diff'] < 0
df['fall'] = df['diff'] > 0

# 计算每日报酬
df['ret'] = df['Close'].pct_change(1)

print(df[['rise', 'fall']].sum()) # 计算涨跌次数
# print(df[df.index > '2018-08-01'])
print(df.loc[df.index > '2018-08-01', ['rise', 'fall']].sum()) # 当月的涨跌次数
print(df.groupby([df.index.year, df.index.month])['rise', 'fall'].sum()) # 根据年月统计涨跌次数
print(df.groupby([df.index.year, df.index.month])['ret'].mean()) # 根据年月统计每月的报酬

推论性统计

资料模型的建构
从样本推论整体资料的概况
相关,回归,因素分析

绘制图表

人是视觉性的动物,百分之七十的接收数据通过眼睛,百分之三十的接收数据通过其它五官(嘴巴,鼻子,耳朵等)

信息图表的功能

  • 沟通已知的信息(Storytelling)
  • 从资料中发现背后的事实(Exploration)

信息可视化

  • 可视化目标:
    有效沟通
    清楚
    完整
    促进参与者的互动
  • 专注在传达的有效性
  • 可视化 + 互动 = 成功的可视化

pands绘制图表

需要安装matplotlib模块

import pandas_datareader as pdd

df = pdd.DataReader('BABA', data_source='yahoo')

# 绘制折线图
df['Close'].plot(kind='line', figsize=[10, 5], legend=True, title='BABA', grid=True)
# lengend=True 图表
# grid 表格

# 绘制移动平均线
df['mvg30'] = df['Close'].rolling(window=30).mean()
df[['Close', 'mvg30']].plot(kind='line', legend=True, figsize=[10, 5])

# 直方图
df.ix[df.index >= '2017-04-01', 'Volume'].plot(kind='bar', figsize[10, 5], title='BABA', legend=True)

# 饼图
df['diff'] = df['Close'] - df['Open']
df['rise'] = df['diff'] > 0
df['fall'] = df['diff'] < 0

df[['rise', 'fall']].sum().plot(kind='pie', figsize[5,5], counterclock=Ture, startangle=90, legend=True)

数据存入

将数据以结构化方式做存储,让用户可以透明结构化查询语言(SQL),快速查询及维护数据。

ACID原则:

  • 不可分割性/原子性(Atomicity): 交易必须全部完成或全部不完成。
  • 一致性(Consistency): 交易开始到结束,数据完整性都符合既设规则与限制
  • 隔离性(Isolation): 并行的交易不会影响彼此
  • 持久性(Durability): 进行完交易后,对数据库的变更会永久保留在数据库

sqlite3

套件,组件。

import sqlite3 as lite

con = lite.connect('test.sqlite') # 连接
cur = con.cursor() # 游标
cur.execute('SELECT SQLITE_VERSION()') # 语句执行
data = cur.fetchone() # 获取一条row

print(data)

con.close()

新增,查询:

import sqlite3 as lite

with lite.connect('test.sqlite') as con:
    cur = con.cursor()
    cur.execute('DROP TABLE IF EXISTS PhoneAddress')
    cur.execute('CREATE TABLE PhoneAddress(phone CHAR(10) PRIMARY KEY, address TEXT, name TEXT unique, age INT NOT NULL)')
    cur.execute('INSERT INTO PhoneAddress VALUES("245345345", "United", "Jsan", 50)')
    cur.execute('SELECT phone,address FROM PhoneAddress')
    data = cur.fetchall()

    for rec in data:
        print(rec[0], rec[1])

fetchonefetchall获取数据根据游标cursor,来获取对应的数据。
操作的逻辑建立在游标之上。

使用Pandas存储数据

  1. 建立DataFrame
  2. 使用Pandas存储数据
import sqlite3 as lite
import pandas

employee = [{
    'name': 'Mary',
    'age': 24,
    'gender': 'F'
}]
df = pandas.DataFrame(employee)

with lite.connect('test.sqlite') as db:
    cur = db.cursor()
    df.to_sql(name='employee', index=False, con=db, if_exists='replace')
    d = pandas.read_sql('SELECT * FROM employee', con=db) # 可以使用SQL语句(聚合查询,排序语句)读取数据,pandas转换成DataFrame格式
    print(d)

    cur.execute('SELECT * FROM employee')
    data = cur.fetchone()
    print(data)

获取国家外汇管理局-人民币汇率中间价

获取数据并处理数据:

import sqlite3 as lite
from datetime import datetime, timedelta

import pandas as pd
import requests
from bs4 import BeautifulSoup

url = 'http://www.safe.gov.cn/AppStructured/hlw/RMBQuery.do'
ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.63.6726.400 QQBrowser/10.2.2265.400'

headers = {
    'User-Agent': ua,
    'Content-Type': 'text/html;charset=UTF-8'
}


def getCurrency(start, end):
    payload = {
        'startDate': start,
        'endDate': end,
        'queryYN': True
    }
    html = requests.post(url, data=payload, headers=headers).text

    soup = BeautifulSoup(html, 'html.parser')

    dfs = pd.read_html(str(soup.select('#InfoTable')[0]), header=0)[0]  # 读取成DataFrame格式数据
    # soup.select('#InfoTable')[0].prettify('UTF-8') 测试的时候出现中文乱码

    dfs = pd.melt(dfs, col_level=0, id_vars='日期')
    dfs.columns = ['date', 'currency', 'exchange']

    with lite.connect('currency.sqlite') as db:
        dfs.to_sql(name='currency', index=None, con=db, if_exists='append')

        cur = db.cursor()
        cur.execute('SELECT * FROM currency')
        data = cur.fetchall()
        print(len(data))


if __name__ == '__main__':
    current_time = datetime.now()

    for i in range(1, 300, 30):
        start_date = (current_time - timedelta(days=i+30)).strftime('%Y-%m-%d')
        end_date = (current_time - timedelta(days=i+1)).strftime('%Y-%m-%d')
        print(start_date, end_date)
        getCurrency(start_date, end_date)

展示图表数据:

import sqlite3 as lite
import pandas as pd

with lite.connect('currency.sqlite') as db:
    df = pd.read_sql('SELECT * FROM currency', con=db)

    df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')

    df.index = df.date
    print(df.head())
    df.plot(kind='line', rot=30, color='blue')
    原文作者:alogy
    原文地址: https://segmentfault.com/a/1190000016486716
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞