python数据分析
python数据分析是一个非常好用的,虽然python数据分析只是刚刚起步,有些功能还未开发完成,但是用来做数据分析是绰绰有余了,本人也是专门研究和学习python数据分析的。
星座数据爬虫
作为一个学习数据分析的人,爬虫是一项必不可少的技能,因为很多数据不是别人提供的,而是需要自己去挖掘出来的,所以就需要自己从网站上爬取数据,这次我们主要是爬取星座屋的数据,因为上面的数据比较全,而且内容也很多。
分析网站
首先我们得进入到要获取数据的网站(https://www.xzw.com/fortune/),然后就可以看到
然后我们就随便进去一个星座看一看。
然后就可以看到数据都在这里了,因为这里的url地址和最原始的不一样,所以我们就需要分析url的变化规则
下面直接给爬虫代码,就不细说爬虫了,不懂也可以来问我。
'''
星座屋爬虫
creat on July 6,2019
@Author 小明
'''
import requests
from bs4 import BeautifulSoup
import re
import pandas as pdheaders = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36","Cookie":"my_city=%E4%BD%9B%E5%B1%B1; my_province=%E5%B9%BF%E4%B8%9C; UM_distinctid=16bb293ac7a584-0ff6fe610b1129-f353163-100200-16bb293ac7b3fc; fc_aid=4; BAIDU_SSP_lcr=https://www.google.com/; CNZZDATA30047636=cnzz_eid%3D942196296-1562064836-https%253A%252F%252Fwww.google.com%252F%26ntime%3D1562415181; CNZZDATA3473983=cnzz_eid%3D338043090-1562064968-https%253A%252F%252Fwww.google.com%252F%26ntime%3D1562416420; CNZZDATA1273458473=346194606-1562068152-https%253A%252F%252Fwww.google.com%252F%7C1562415193"}xz_lst = ['leo','libra','scorpio','aquarius','taurus','gemini','cancer','virgo','sagittarius','capricorn','pisces','aries']data_time = pd.date_range(start='20190101',end='20190706',freq='D')
date_list = [re.match("(.*?)T",str(i)).group(1) for i in data_time.values]
date = [re.sub("-","",j) for j in date_list]url_list = []
for i in xz_lst:for j in date:url = "https://www.xzw.com/fortune/{0}/{1}.html".format(i,j)url_list.append(url)
data_list = []
for u in url_list:response = requests.get(url=u, headers=headers)print(response)soupi = BeautifulSoup(response.text, 'lxml')# 解析页面try:dic = {}dic['标题'] = soupi.find('h4').text# 获取标题信息infor1 = soupi.find('div', class_="c_main").find('ul').find_all('li')dic[infor1[0].text] = infor1[0].find('em')['style'].split(':')[1].split('p')[0]dic[infor1[1].text] = infor1[1].find('em')['style'].split(':')[1].split('p')[0]dic[infor1[2].text] = infor1[2].find('em')['style'].split(':')[1].split('p')[0]dic[infor1[3].text] = infor1[3].find('em')['style'].split(':')[1].split('p')[0]dic[infor1[4].find('label').text] = infor1[4].text.split(':')[1]dic[infor1[5].find('label').text] = infor1[5].text.split(':')[1]dic[infor1[6].find('label').text] = infor1[6].text.split(':')[1]dic[infor1[7].find('label').text] = infor1[7].text.split(':')[1]dic[infor1[8].find('label').text] = infor1[8].text.split(':')[1]dic[infor1[9].find('label').text] = infor1[9].text.split(':')[1]# 获取运势等信息infor2 = soupi.find('div', class_="c_cont").find_all('p')dic['综合运势文字'] = infor2[0].find('span').textdic['爱情运势文字'] = infor2[1].find('span').textdic['事业学业文字'] = infor2[2].find('span').textdic['财富运势文字'] = infor2[3].find('span').textdic['健康运势文字'] = infor2[4].find('span').textprint(dic)data_list.append(dic)except:print("网页为空")pass
data_frame = pd.DataFrame(data_list)
pd.DataFrame.to_csv(data_frame,"I:/crack/DATA/xingzuo.csv",encoding="utf_8_sig")
print("写入成功")
用综合运势的文字来制作云图
首先导入数据
from cv2 import imread
import pandas as pd
import jieba
import matplotlib.pyplot as plt
import wordcloud
from scipy.interpolate import spline
import numpy as nppd.set_option('display.max_columns',1000)
pd.set_option('display.width',150)
pd.set_option('display.max_colwidth',500)
data = pd.read_csv("I:/crack/DATA/xingzuo.csv")
这里面的pd.set_option(‘display.max_columns’,1000),pd.set_option(‘display.width’,150)
pd.set_option(‘display.max_colwidth’,500) 是用来在pycharm中更好的显示数据的,如果不加上这三行代码,读取数据的时候会省略一些,不显示完,加不加都没关系,加了只是为了更好的观察数据。
清洗标题文字和获取综合运势的文字
data["标题"] = data["标题"].str[:3] # 首先要将标题只截取出来星座的名字
all_fortune = data[data["标题"] == "处女座"]["综合运势文字"].tolist()
all_fortune_txt = "".join(all_fortune)
word_list = jieba.cut(all_fortune_txt)
txt = "".join(word_list)
因为在爬取数据的时候也把日期爬取出来了,比如处女座运势1月1日,但是我们在截取数据的时候想把处女座给提取出来,所以就用str[:3]的方法把原标题的文字转换成我们想
要的文字。
然后把综合运势的文字转换成列表里面的一个一个元素,然后再拼成一段话,再用结巴进行分词,然后再把一些词合成一句一句完整的句子。
画云图
w = wordcloud.WordCloud(font_path = "I:crack/font/msyh.TTF",width = 1000,height = 700,background_color = "FloralWhite").generate(txt)
plt.imshow(w) #显示图片
plt.show()
w.to_file("I:/crack/img/fortune.png") #保存图片
这里的云图有很多参数,为了方便使用,我就直接把每个参数是用来做什么的,写在下面
# font_path : string //字体路径,需要展现什么字体就把该字体路径+后缀名写上,如:font_path = '黑体.ttf'
#
# width : int (default=400) //输出的画布宽度,默认为400像素
#
# height : int (default=200) //输出的画布高度,默认为200像素
#
# prefer_horizontal : float (default=0.90) //词语水平方向排版出现的频率,默认 0.9 (所以词语垂直方向排版出现频率为 0.1 )
# mask : nd-array or None (default=None) //如果参数为空,则使用二维遮罩绘制词云。如果 mask 非空,设置的宽高值将被忽略,遮罩形状被 mask 取代。除全白(#FFFFFF)的部分将不会绘制,其余部分会用于绘制词云。如:bg_pic = imread('读取一张图片.png'),背景图片的画布一定要设置为白色(#FFFFFF),然后显示的形状为不是白色的其他颜色。可以用ps工具将自己要显示的形状复制到一个纯白色的画布上再保存,就ok了。
#
# scale : float (default=1) //按照比例进行放大画布,如设置为1.5,则长和宽都是原来画布的1.5倍。
#
# min_font_size : int (default=4) //显示的最小的字体大小
#
# font_step : int (default=1) //字体步长,如果步长大于1,会加快运算但是可能导致结果出现较大的误差。
#
# max_words : number (default=200) //要显示的词的最大个数
#
# stopwords : set of strings or None //设置需要屏蔽的词,如果为空,则使用内置的STOPWORDS
#
# background_color : color value (default=”black”) //背景颜色,如background_color='white',背景颜色为白色。
#
# max_font_size : int or None (default=None) //显示的最大的字体大小
#
# mode : string (default=”RGB”) //当参数为“RGBA”并且background_color不为空时,背景为透明。
#
# relative_scaling : float (default=.5) //词频和字体大小的关联性
#
# color_func : callable, default=None //生成新颜色的函数,如果为空,则使用 self.color_func
#
# regexp : string or None (optional) //使用正则表达式分隔输入的文本
#
# collocations : bool, default=True //是否包括两个词的搭配
#
# colormap : string or matplotlib colormap, default=”viridis” //给每个单词随机分配颜色,若指定color_func,则忽略该方法。
#
#
#
# fit_words(frequencies) //根据词频生成词云
# generate(text) //根据文本生成词云
# generate_from_frequencies(frequencies[, ...]) //根据词频生成词云
# generate_from_text(text) //根据文本生成词云
# process_text(text) //将长文本分词并去除屏蔽词(此处指英语,中文分词还是需要自己用别的库先行实现,使用上面的 fit_words(frequencies) )
# recolor([random_state, color_func, colormap]) //对现有输出重新着色。重新上色会比重新生成整个词云快很多。
# to_array() //转化为 numpy array
# to_file(filename) //输出到文件
源码
'''
星座数据分析
creat on July 6,2019
@Author 小明
'''
from cv2 import imread
import pandas as pd
import jieba
import matplotlib.pyplot as plt
import wordcloud
from scipy.interpolate import spline
import numpy as nppd.set_option('display.max_columns',1000)
pd.set_option('display.width',150)
pd.set_option('display.max_colwidth',500)#首先制作词云图,处女座半年来的运势分析
data = pd.read_csv("I:/crack/DATA/xingzuo.csv")
def ciyun():data["标题"] = data["标题"].str[:3] # 首先要将标题只截取出来星座的名字all_fortune = data[data["标题"] == "处女座"]["综合运势文字"].tolist()print(all_fortune)all_fortune_txt = "".join(all_fortune)print(all_fortune)#将综合运势的文字进行切片word_list = jieba.cut(all_fortune_txt)txt = "".join(word_list)#开始画云图,注意这里时要根据文本画云图,如果需要根据词频画图那就是调用fit_wordsw = wordcloud.WordCloud(font_path = "I:crack/font/msyh.TTF",width = 1000,height = 700,background_color = "FloralWhite").generate(txt)plt.imshow(w) #显示图片plt.show()w.to_file("I:/crack/img/fortune.png") #保存图片
注意:因为我个人是处女座,我就把处女座的截取出来制作成云图。
将综合运势走向制作成曲线图
读取数据
from cv2 import imread
import pandas as pd
import jieba
import matplotlib.pyplot as plt
import wordcloud
from scipy.interpolate import spline
import numpy as nppd.set_option('display.max_columns',1000)
pd.set_option('display.width',150)
pd.set_option('display.max_colwidth',500)
data = pd.read_csv("I:/crack/DATA/xingzuo.csv")
清洗标题和把综合运势的数据提取出来
data_1 = data.set_index("标题",drop=False)
data_1.index = data_1.index.str[5:]
data_1.index.name = "date"
data_1["标题"] = data_1["标题"].str[:3]
data_2 = data_1[data_1["标题"] == "处女座"]
这里我把标题转换为了行索引,方便下面要制作曲线图的x轴坐标
画图
plt.figure(figsize=(12,8))
plt.rcParams["font.family"] = "SimHei"
x = data_2.index[::10]
y = data_2["综合运势:"].tolist()[::10]
x_xtick = np.arange(len(x))
xnew = np.linspace(x_xtick.min(), x_xtick.max(), 300) # 定义曲线的X和Y值
power_smooth_1 = spline(x_xtick, y, xnew)
plt.plot(xnew, power_smooth_1)
plt.xticks(range(len(x)),x,fontsize=16,rotation=45)
plt.yticks([i*16 for i in range(5)])
plt.grid()
plt.savefig("I:/crack/img/处女座综合运势走向图.png", bbox_inches="tight")
plt.show()
因为这里的数据太多了,日期太多了,如果一个一个都显示的话就很难看出什么,图片也很难观察,所以这样x = data_2.index[::10]
y = data_2[“综合运势:”].tolist()[::10] 用切片的方式来间隔显示数据,这里画曲线的思路是,先按照折线的方式画图,然后再把每个点连接起来画成曲线图,不懂也可以去百度看一看,都会有很详细的解说的。
这里为了更好的显示,也画了网格线,因为综合运势是有序的分类变量,所以我们可以按照它的顺序来做y轴的刻度。
源码
'''
星座数据分析
creat on July 6,2019
@Author 小明
'''
from cv2 import imread
import pandas as pd
import jieba
import matplotlib.pyplot as plt
import wordcloud
from scipy.interpolate import spline
import numpy as nppd.set_option('display.max_columns',1000)
pd.set_option('display.width',150)
pd.set_option('display.max_colwidth',500)data = pd.read_csv("I:/crack/DATA/xingzuo.csv")#分析处女座综合运势走向,画曲线图
def fortuen():data_1 = data.set_index("标题",drop=False)data_1.index = data_1.index.str[5:]data_1.index.name = "date"data_1["标题"] = data_1["标题"].str[:3]data_2 = data_1[data_1["标题"] == "处女座"]#画图plt.figure(figsize=(12,8))plt.rcParams["font.family"] = "SimHei"x = data_2.index[::10]y = data_2["综合运势:"].tolist()[::10]x_xtick = np.arange(len(x))xnew = np.linspace(x_xtick.min(), x_xtick.max(), 300) # 定义曲线的X和Y值power_smooth_1 = spline(x_xtick, y, xnew)plt.plot(xnew, power_smooth_1)plt.xticks(range(len(x)),x,fontsize=16,rotation=45)plt.yticks([i*16 for i in range(5)])plt.grid()plt.savefig("I:/crack/img/处女座综合运势走向图.png", bbox_inches="tight")plt.show()
注意:不懂的也可以看我前面的博客,或者来问我也许。
画爱情云图
import pandas as pd
import jieba
import wordcloud
from cv2 import imread
import numpy as np
import matplotlib.pyplot as plt#现在来看一下三个月处女座综合运势的分析,词云
pd.set_option('display.max_columns',1000)
pd.set_option('display.width',150)
pd.set_option('display.max_colwidth',500)
data = pd.read_csv("I:/crack/DATA/xingzuo.csv")data["标题"] = data["标题"].str[:3] #首先将标题转化为只有星座的模样data_virgo = data[data["标题"] == "处女座"]word = data_virgo["爱情运势文字"].tolist()
all_word = "".join(word)#然后用解霸来分析文字
word_list = jieba.cut(all_word,cut_all=False)
txt = "".join(word_list)
#来尝试制作爱心的词云图,要导入cv2中的imread这个模块
pic = imread("I:/crack/img/1.png")#然后读出这个图片
w_2 = wordcloud.WordCloud(mask=pic,font_path = "I:crack/font/msyh.TTF",width = 758,height = 659,background_color = "white")
w_2.generate(txt)
plt.imshow(w_2, interpolation="bilinear")
plt.show()
w_2.to_file("I:/crack/img/chi4.png")
这里和上面的综合运势的云图没有什么大的区别,唯一不同的就是,这里的云图模型是爱心型的。
首先要找到像素为爱心型的图片,然后用cv2中的imread来读取爱心的轮廓,然后在云图的参数里面的mask传递读取的对象就可以了
源码
import pandas as pd
import jieba
import wordcloud
from cv2 import imread
from PIL import Image
from os import path
import numpy as np
import matplotlib.pyplot as plt#现在来看一下三个月处女座综合运势的分析,词云
pd.set_option('display.max_columns',1000)
pd.set_option('display.width',150)
pd.set_option('display.max_colwidth',500)
data = pd.read_csv("I:/crack/DATA/xingzuo.csv")data["标题"] = data["标题"].str[:3] #首先将标题转化为只有星座的模样data_virgo = data[data["标题"] == "处女座"]word = data_virgo["爱情运势文字"].tolist()
all_word = "".join(word)#然后用解霸来分析文字
word_list = jieba.cut(all_word,cut_all=False)
txt = "".join(word_list)#然后先制作一个简单的词云
# w = wordcloud.WordCloud(font_path = "I:crack/font/msyh.TTF",width = 1000,height = 700,background_color = "Pink") #这个是配置词云设置#来尝试制作爱心的词云图,要导入cv2中的imread这个模块
pic = imread("I:/crack/img/1.png")#然后读出这个图片
w_2 = wordcloud.WordCloud(mask=pic,font_path = "I:crack/font/msyh.TTF",width = 758,height = 659,background_color = "white")
w_2.generate(txt)
plt.imshow(w_2, interpolation="bilinear")
plt.show()
w_2.to_file("I:/crack/img/chi4.png")
分析处女座与其他星座匹配的频数
首先读取数据
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import splinedata = pd.read_csv("I:/crack/DATA/xingzuo.csv")
然后提取数据
data["标题"] = data["标题"].str[:3]
data_1 = data[data["标题"] == "处女座"]
data_1 = data_1["速配星座:"].value_counts()
这里用到了频数统计,就是先把处女座的数提取出来,然后分类统计出速配星座的频数。
画图
源码
'''
星座分析
creat on July 7,2019
@Author 小明
'''
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import splinedata = pd.read_csv("I:/crack/DATA/xingzuo.csv")#分析这段时间处女座和其他星座匹配的频数统计
def match():data["标题"] = data["标题"].str[:3]data_1 = data[data["标题"] == "处女座"]data_1 = data_1["速配星座:"].value_counts()plt.figure(figsize=(12, 9))plt.rcParams["font.family"] = "SimHei"x = data_1.indexy = data_1.valuesrect = plt.bar(range(len(x)), y,color = "Pink")plt.xticks(range(len(x)),x,fontsize = 15)for rects in rect:height = rects.get_height()plt.text(rects.get_x() + rects.get_width()/2,1.02*height, height,fontsize = 18,ha='center')plt.savefig("I:/crack/img/处女座与其他星座匹配的频数.png")plt.show()