python科学计算之numpy+pandas+matplotlib+mysql

简介

本文主要介绍了读取mysql中的数据,将其保存至numpy和pandas中,通过matplotlib进行可视化数据分析。

一、环境搭建
使用anaconda搭建科学计算环境,并安装相关软件包。

conda create -n science python=2 numpy pandas matplotlib
source activate science 
pip install mysql-python

二、生成2014每月数据柱状图

mysql> select Y,M,Sale from Yield where proptype=11 and tjtype=1 and datatype=1 and Y=2014;
+------+----+----------------+
| Y    | M  | Sale           |
+------+----+----------------+
| 2014 |  1 |   37203.854772 |
| 2014 |  2 |   38865.132825 |
| 2014 |  3 |   40261.427668 |
| 2014 |  4 |   38536.986551 |
| 2014 |  5 |   38573.389336 |
| 2014 |  6 |   37604.819697 |
| 2014 |  7 |   37270.686865 |
| 2014 |  8 |   35562.201465 |
| 2014 |  9 |   36258.556955 |
| 2014 | 10 |   36421.066626 |
| 2014 | 11 |   36796.768594 |
| 2014 | 12 |   25064.590895 |
+------+----+----------------+

#!/usr/local/miniconda2/envs/science/bin/python
#-*- coding: utf-8 -*-

import MySQLdb
import numpy as np
import matplotlib.pyplot as plt

db=MySQLdb.connect(host="10.10.89.11",user='test',passwd="test",port=3306,db="dbtest")
cursor=db.cursor()
sql="select Y,M,Sale from Yield where proptype=11 and tjtype=1 and datatype=1 and Y=2014"
cursor.execute(sql)
result=cursor.fetchall()
#定义结构数组的数据类型
qushi=np.dtype([('Y','i2'),('M','i2'),('Sale','f4')])
data=np.fromiter(result,dtype=qushi,count=-1)
#字体设置
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['simhei']
plt.rcParams['axes.unicode_minus'] = False
#柱状图
plt.bar(data['M'],data['Sale'],align='center')
plt.title(u'2014趋势')
plt.xlabel(u'月份')
plt.ylabel(u'价格')
plt.xticks(data['M'])
plt.show()

db.close()

这里写图片描述
要点:
1.由于从mysql读取的数据字段的数据类型不同,因此需要对每个字段重新定义。在此我们先定义了一个qushi的dtype对象,通过其字典参数描述结构类型的各个字段。
2.从mysql读取的数据为元组,需要通过fromiter函数从任何可迭代对象构建一个ndarray对象,返回一个新的一维数组。
3.字体设置
matplotlib默认无法显示中文,按代码中设置若报错”UserWarning: findfont: Font family [u’sans-serif’] not found”
需要将下载的simhei.tty字体放到”/usr/local/miniconda2/envs/science/lib/python2.7/site-packages/matplotlib/mpl-data/fonts/tty”目录下;若有字体但还是显示小方块,一般是没有删除/root/.cache/matplotlib 的缓冲目录
或用如下设置

#中文字体解决
ziti = path.join(mulu, 'simsun.ttc')
font = FontProperties(fname=ziti, size=14)
plt.title(u'2014趋势',fontproperties=font)
plt.xlabel(u'月份',fontproperties=font)
plt.ylabel(u'价格',fontproperties=font)

三.生成2013年和2014年月份对比图
Series和DataFrame都有一个用于生成各类图标的plot方法,默认情况下,他们所生成的是线型图,该Series的索引会被传给matplotlib,并用于绘制x轴。
在生成的线型图的代码中加上kind=’bar’(垂直树状图)或 kind=’barch’(水平柱状图)即可生成柱状图,此时,Series和DataFrame的索引将会被用作X或Y的刻度。

注意:绘制线型图或柱状图需要编排series和dataframe的格式如下:

#合并并重新指定index后的新dataframe,否则index从0开始与月份不对应
#print new11

        2013data      2014data
m1                            
1   32056.771282  37203.854772
2   32987.785092  38865.132825
3   35206.157730  40261.427668
4   35159.787179  38536.986551
5   35138.053408  38573.389336
6   35291.460982  37604.819697
7   36220.846603  37270.686865
8   36734.851022  35562.201465
9   37354.185789  36258.556955
10  37930.002182  36421.066626
11  38259.861458  36796.768594
12  37946.747888  25064.590895

因为对于DataFrame,柱状图会将每一行的值分为一组。但是我们从mysql读取的数据不是这样的,所以我们需要通过dataframe的concat来合并,并修改index才能得到上面的格式。

#!/usr/local/miniconda2/envs/science/bin/python
#-*- coding: utf-8 -*-

import pandas as pd
import matplotlib.pyplot as plt
import MySQLdb

db=MySQLdb.connect(host="10.10.89.11",user='test',passwd="test",port=3306,db="dbtest")
sql2014="select Y,M as 'm1',Sale as '2014data' from Yield where proptype=11 and tjtype=1 and datatype=1 and Y=2014"
sql2013="select Y,M,Sale as '2013data' from Yield where proptype=11 and tjtype=1 and datatype=1 and Y=2013"
#通过read_sql读取数据
df2014=pd.read_sql(sql2014,con=db)
df2013=pd.read_sql(sql2013,con=db)
#横向合并dataframe
new=pd.concat([df2014,df2013],axis=1)
#获取相关列
new_df=new[["m1","2013data","2014data"]]
#将m1列指定为index,否则index默认为0-12
new11=new_df.set_index("m1")

plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['simhei']
plt.rcParams['axes.unicode_minus'] = False
#线型图
#new11.plot()
#柱状图
new11.plot(kind='bar')
plt.xlabel(u"月份")
plt.ylabel(u"销售数据")
plt.show()

db.close

这里写图片描述
这里写图片描述
要点:
1.read_sql的参数index_col制定某列为索引列,通过此设置,我们concat后就不用set_index了。

df2014=pd.read_sql(sql2014,con=db,index_col='M')
df2013=pd.read_sql(sql2013,con=db,index_col='M')

new=pd.concat([df2014,df2013],axis=1)

new_df=new[["2013data","2014data"]]
print new_df
#打印数据
        2013data      2014data
M                             
1   32056.771282  37203.854772
2   32987.785092  38865.132825
3   35206.157730  40261.427668
4   35159.787179  38536.986551
5   35138.053408  38573.389336
6   35291.460982  37604.819697
7   36220.846603  37270.686865
8   36734.851022  35562.201465
9   37354.185789  36258.556955
10  37930.002182  36421.066626
11  38259.861458  36796.768594
12  37946.747888  25064.590895
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值