‘壹’ 如何用 python 分析网站日志
日志的记录
Python有一个logging模块,可以用来产生日志。
(1)学习资料
http://blog.sina.com.cn/s/blog_4b5039210100f1wv.html
http://blog.donews.com/limodou/archive/2005/02/16/278699.aspx
http://kenby.iteye.com/blog/1162698
http://blog.csdn.NET/fxjtoday/article/details/6307285
前边几篇文章仅仅是其它人的简单学习经验,下边这个链接中的内容比较全面。
http://www.red-dove.com/logging/index.html
(2)我需要关注内容
日志信息输出级别
logging模块提供了多种日志级别,如:NOTSET(0),DEBUG(10),
INFO(20),WARNING(30),WARNING(40),CRITICAL(50)。
设置方法:
logger = getLogger()
logger.serLevel(logging.DEBUG)
日志数据格式
使用Formatter设置日志的输出格式。
设置方法:
logger = getLogger()
handler = loggingFileHandler(XXX)
formatter = logging.Formatter("%(asctime)s %(levelname) %(message)s","%Y-%m-%d,%H:%M:%S")
%(asctime)s表示记录日志写入时间,"%Y-%m-%d,%H:%M:%S“设定了时间的具体写入格式。
%(levelname)s表示记录日志的级别。
%(message)s表示记录日志的具体内容。
日志对象初始化
def initLog():
logger = logging.getLogger()
handler = logging.FileHandler("日志保存路径")
formatter = logging.Formatter("%(asctime)s %(levelname) %(message)s","%Y-%m-%d,%H:%M:%S")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel
写日志
logging.getLogger().info(), logging.getLogger().debug()......
2. 日志的分析。
(1)我的日志的内容。(log.txt)
2011-12-12,12:11:31 INFO Client1: 4356175.0 1.32366309133e+12 1.32366309134e+12
2011-12-12,12:11:33 INFO Client1: 4361320.0 1.32366309334e+12 1.32366309336e+12
2011-12-12,12:11:33 INFO Client0: 4361320.0 1.32366309389e+12 1.32366309391e+12
2011-12-12,12:11:39 INFO Client1: 4366364.0 1.32366309934e+12 1.32366309936e+12
2011-12-12,12:11:39 INFO Client0: 4366364.0 1.32366309989e+12 1.32366309991e+12
2011-12-12,12:11:43 INFO Client1: 4371416.0 1.32366310334e+12 1.32366310336e+12
2011-12-12,12:11:43 INFO Client0: 4371416.0 1.32366310389e+12 1.32366310391e+12
2011-12-12,12:11:49 INFO Client1: 4376450.0 1.32366310934e+12 1.32366310936e+12
我需要将上述内容逐行读出,并将三个时间戳提取出来,然后将其图形化。
(2) 文件操作以及字符串的分析。
打开文件,读取出一行日志。
file = file("日志路径",“r”)
while True:
line = file.readline()
if len(len) == 0:
break;
print line
file.close()
从字符串中提取数据。
字符串操作学习资料:
http://reader.you.com/sharelite?itemId=-4646262544179865983&method=viewSharedItemThroughLink&sharedBy=-1137845767117085734
从上面展示出来的日志内容可见,主要数据都是用空格分隔,所以需要使用字符串的
split函数对字符串进行分割:
paraList = line.split(),该函数默认的分割符是空格,返回值为一个list。
paraList[3], paraList[4], paraList[5]中分别以字符串形式存储着我需要的时间戳。
使用float(paraList[3])将字符串转化为浮点数。
(3)将日志图形化。
matplotlib是python的一个绘图库。我打算用它来将日志图形化。
matplotlib学习资料。
matplotlib的下载与安装:
http://yexin218.iteye.com/blog/645894
http://blog.csdn.Net/sharkw/article/details/1924949
对matplotlib的宏观介绍:
http://apps.hi..com/share/detail/21928578
对matplotlib具体使用的详细介绍:
http://blog.sina.com.cn/s/blog_4b5039210100ie6a.html
在matplotlib中设置线条的颜色和形状:
http://blog.csdn.net/kkxgx/article/details/python
如果想对matplotlib有一个全面的了解,就需要阅读教程《Matplotlib for Python developers》,教程下载地址:
http://download.csdn.net/detail/nmgfrank/4006691
使用实例
import matplotlib.pyplot as plt
listX = [] #保存X轴数据
listY = [] #保存Y轴数据
listY1 = [] #保存Y轴数据
file = file("../log.txt","r")#打开日志文件
while True:
line = file.readline()#读取一行日志
if len(line) == 0:#如果到达日志末尾,退出
break
paraList = line.split()
print paraList[2]
print paraList[3]
print paraList[4]
print paraList[5]
if paraList[2] == "Client0:": #在坐标图中添加两个点,它们的X轴数值是相同的
listX.append(float(paraList[3]))
listY.append(float(paraList[5]) - float(paraList[3]))
listY1.append(float(paraList[4]) - float(paraList[3]))
file.close()
plt.plot(listX,listY,'bo-',listX,listY1,'ro')#画图
plt.title('tile')#设置所绘图像的标题
plt.xlabel('time in sec')#设置x轴名称
plt.ylabel('delays in ms'')#设置y轴名称
plt.show()
‘贰’ 数据蛙-Python进阶
这是漫长的一周,本周完成了Python的进阶模块,主要是pandas、numpy、matplotlib、seaborn、pyecharts这些模块的学习以及一个实际的案例:商品销售情况分析,之前一直觉得课程难度不够,但到这一周难度就大大提高了。尤其是案例练习中的RFM模型和用户生命周期建立,看懂不难但是自差首己写一直出错,在不断出错不断尝试中知识得到了积累,另外可视化部分没有什么练习题,希望后面可以加上一些这方面的练习,接下来分模块来总结一下学习的内容。
重新设置索引:df.set_index()
Series格式转换为DataFrame:df.to_frame()
文件读取:pd.read_csv(filepath, header = 0,skiprows=[1,2])
使用位禅庆源置做索引:df.loc[0] 使用列表做索引:df.loc[[0,1,2]]
使用切片做索引:df.loc[0:4] 使用bool类型索引:df[df['年龄']>30]
loc 是基于索引值的,切片是左闭右闭的
iloc 是基于位置的,切片是左闭右开的
修改列索引:df.rename(columns={'姓名':'name', '年龄':'age'},inplace=True)
替换一个值:df.replace({'name':{'小明':'xiaoming'}},inplace=True)
对数据进行排序:df.sort_values('age')
累加求和:df.cumsum(0)
删除列:del df['player'] 删除行:df.drop(labels=0) labels 是行列的名字
数据拼接:pd.concat([left,right],axis=1)
# 指定列进行关联,默认是 inner join result = pd.merge(left,right,on='key')
#多个关联条件:result = pd.merge(left, right, on=['key1', 'key2'])
#左连接:result = pd.merge(left, right, how='left', on=['key1', 'key2'])
# 列名不一样的关联:pd.merge(left,right,left_on = ['key1','key2'],right_on = ['key3','key4'])
#单个分组:groups = df.groupby('district')
# 作用多个聚合函数:groups.agg([np.mean,np.sum,np.std])
# 针对具体列聚合 groups.age.agg([np.mean,np.sum,np.std])
# 不同列不同聚合函数 groups.agg({"age":np.mean,"novip_buy_times":np.sum})
分组后该列值求和显示:groups['vip_buy_times'].transform('sum')
通常用于求占比:transform(lambda x: x /sum(x))
# 填充指定值:np.full([3,4],1)
# 起始为10,5为步长,30为结贺态尾取不到:np.arange(10, 30, 5)
#随机矩阵:np.random.random((2,3))
# 平均划分:np.linspace( 0, 2*pi, 100 )
# 类型及转换:vector.astype('float')
# 多维变一维:matrix.ravel()
# 矩阵的扩展:a = np.arange(0, 40, 10) b = np.tile(a, (3, 5)) # 行变成3倍,列变成5倍
# 水平拼接:np.hstack((a,b)) 竖直拼接:np.vstack((a,b))
# 竖直分割:np.hsplit(a,3) #水平分割:np.vsplit(a,3)
8. Select the data in rows [3, 4, 8] and in columns ['animal', 'age'].
A:df.loc[df.index[[3,4,8]],['animal','age']]
行采用位置,列采用普通索引,这里利用index函数将位置变化为具体的普通索引,再利用loc函数
19. The 'priority' column contains the values 'yes' and 'no'. Replace this column with a column of boolean values: 'yes' should be True and 'no' should be False
A1:df['priority'].replace(['yes','no'],[True,False],inplace=True) 用replace函数替换
A2:df['priority'] = df['priority'].map({'yes': True, 'no': False}) 用map函数替换
最大最小值的索引:df.idxmax、df.idxmin
找出最大最小的前N个数:nlargest()和nsmallest()
将原表分组 并设置分段区间 pd.cut(df['A'], np.arange(0, 101, 10))
resample函数 日期重采样:s.resample('M').mean()
TimeGrouper 重组:s.groupby(pd.TimeGrouper('4M')).idxmax()
split 分割函数:temp = df['From_To'].str.split('_', expand=True) True为DataFrame
两个DataFrame拼接用join:df = df.join(temp)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
%matplotlib inline 直接显示
折线图:plt.plot(x,y,color = 'r')
柱状图:plt.bar(x,y) plt.barh(x,y) 多个bar x设置不同 堆积图 bottom设置不同
散点图:plt.scatter(x, y, c=colors, alpha=0.5, s = area)
直方图:plt.hist(a,bins= 20) bin代表分隔的最小单位
plt.legend() 显示图例
for a,b in zip(X+W[i],data[i]):
plt.text(a,b,"%.0f"% b,ha="center",va= "bottom") 添加数据标签
plt.annotate('注释文本',xy=(1, np.sin(1)),xytext=(2, 0.5), fontsize=16,arrowprops=dict(arrowstyle="->")) 添加注释文本
plt.xlabel("Group") x轴标题
plt.ylabel("Num") y轴标题
fig, axes = plt.subplots(nrows=2, ncols=2,facecolor='darkslategray') 绘制多个图形
axes[0,0] axes[0,1] axes[1,0] axes[1,1]
pylab.rcParams['figure.figsize'] = (10, 6) # 调整图片大小
动态展示图表
from pyecharts.charts import Bar
from pyecharts import options as opts
** pyecharts 绘图的五个步骤:**
创建图形对象:bar = Bar()
添加绘图数据:bar.add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
bar.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
bar.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
配置系列参数:对标签、线型等的一些设置
配置全局参数:bar.set_global_opts(title_opts=opts.TitleOpts(title="销售情况"))
渲染图片:生成本地 HTML 文件 bar.render("mycharts.html") bar.render()
notebook 渲染:bar.render_notebook()
bar = (Bar()
.add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
.set_global_opts(title_opts=opts.TitleOpts(title="某商场销售情况"))
)
bar.render_notebook()
柱状图:Bar()
条形图:bar.reversal_axis() #翻转XY轴,将柱状图转换为条形图
折线图:from pyecharts.charts import Line line=Line()
饼图:from pyecharts.charts import Page, Pie Pie()
转换日期类型:df['order_dt']=pd. to_datetime (df.order_dt,format="%Y%m%d")
将日期转换为月为单位:df['month']=df.order_dt.values. astype('datetime64[M]') 所有日期显示为当月第一天
去除日期单元值:order_diff/ np.timedelta64(1,'D')
过滤部分极值:grouped_user.sum() .query('order_procts<100') .order_amount
数据透视表:rfm=df.pivot_table( index ='user_id', values =['order_procts','order_amount'], aggfunc ={'order_amount':'sum','order_procts':'sum'})
map() 方法是pandas.series.map()方法, 对DF中的元素级别的操作, 可以对df的某列或某多列
applymap(func) 也是DF的属性, 对整个DF所有元素应用func操作
purchase_r=pivoted_counts.applymap(lambda x: 1 if x>1 else np.NaN if x==0 else 0)
apply(func) 是DF的属性, 对DF中的行数据或列数据应用func操作,也可用于Series
apply(lambda x:x.cumsum()/x.sum()) 累计占比
apply(lambda x:x/x.sum(),axis=0) 每一列中每行数据占比
下周开始进入数据分析思维的课程,很期待后面的课程以及项目,加油!
‘叁’ python计算每两个向量之间的距离并保持到矩阵中
在很多算法中都会涉及到求向量欧式距离,例如机器学习中的KNN算法,就需要对由训练集A和测试集B中的向量组成的所有有序对(Ai,Bi),求出Ai和Bi的欧式距离。这样的话就会带来一个二重的嵌套循环,在向量集很大时效率不高。
这里介绍如何将这一过程用矩阵运算实现。
假设有两个三维向量集,用矩阵表示:
A=[a11a12a21a22a31a32]
B=⎡⎣⎢⎢b11b12b13b21b22b23b31b32b33⎤⎦⎥⎥
要求A,B两个集合中的元素两两间欧氏距离。
先求出ABT:
ABT=⎡⎣⎢⎢⎢⎢⎢∑k=13ak1bk1∑k=13ak2bk1∑k=13ak1bk2∑k=13ak2bk2∑k=13ak1bk3∑k=13ak2bk3⎤⎦⎥⎥⎥⎥⎥
然后对A和BT分别求其中每个向量的模平方,并扩展为2*3矩阵:
Asq=⎡⎣⎢⎢⎢⎢⎢∑k=13(ak1)2∑k=13(ak2)2∑k=13(ak1)2∑k=13(ak2)2∑k=13(ak1)2∑k=13(ak2)2⎤⎦⎥⎥⎥⎥⎥
Bsq=⎡⎣⎢⎢⎢⎢⎢∑k=13(bk1)2∑k=13(bk1)2∑k=13(bk2)2∑k=13(bk2)2∑k=13(bk3)2∑k=13(bk3)2⎤⎦⎥⎥⎥⎥⎥
然后:
Asq+Bsq−2ABT=⎡⎣⎢⎢⎢⎢⎢∑k=13(ak1−bk1)2∑k=13(ak2−bk1)2∑k=13(ak1−bk2)2∑k=13(ak2−bk2)2∑k=13(ak1−bk3)2∑k=13(ak2−bk3)2⎤⎦⎥⎥⎥⎥⎥
将上面这个矩阵一开平方,就得到了A,B向量集两两间的欧式距离了。
下面是Python实现:
import numpy
def EuclideanDistances(A, B):
BT = B.transpose()
vecProd = A * BT
SqA = A.getA()**2
sumSqA = numpy.matrix(numpy.sum(SqA, axis=1))
sumSqAEx = numpy.tile(sumSqA.transpose(), (1, vecProd.shape[1]))
SqB = B.getA()**2
sumSqB = numpy.sum(SqB, axis=1)
sumSqBEx = numpy.tile(sumSqB, (vecProd.shape[0], 1))
SqED = sumSqBEx + sumSqAEx - 2*vecProd
ED = (SqED.getA())**0.5
return numpy.matrix(ED)
‘肆’ python最优分箱中woe计算(求大圣)
>>> list =[None,None,None,None,"a","b","c",None,"d",12,None,2,4,5,4]>>> list = list[4:]>>> len(list)11>>州虚> list['a', 'b', 'c', None, 'd', 12, None, 2, 4, 5, 4]>>>#如果你的册拍燃list 格式是相同的 比如前面4个都是None,这贺扒个格式是固定的,那么切片很容易解决
‘伍’ 如何用Python绘制JS地图
Folium是建立在Python生态系统的数据整理(Datawrangling)能力和Leaflet.js库的映射能力之上的开源库。用Python处理数据,然后用Folium将它在Leaflet地图上进行可视化。
概念
Folium能够将通过Python处理后的数据轻松地在交互式的Leaflet地图上进行可视化展示。它不单单可以在地图上展示数据的分布图,还可以使用Vincent/Vega在地图上加以标记。
这个开源库中有许多来自OpenStreetMap、MapQuest Open、MapQuestOpen
Aerial、Mapbox和Stamen的内建地图元件,而且支持使用Mapbox或Cloudmade的API密钥来定制个性化的地图元件。
Folium支持GeoJSON和TopoJSON两种文件格式的叠加,也可以将数据连接到这两种文件格式的叠加层,最后可使用color-brewer
配色方案创建分布图。
安装
安装folium包
开始创建地图
创建底图,传入起始坐标到Folium地图中:
importfolium
map_osm= folium.Map(location=[45.5236, -122.6750]) #输入坐标
map_osm.create_map(path='osm.html')
Folium默认使用OpenStreetMap元件,但是Stamen Terrain, Stamen Toner, Mapbox Bright 和MapboxControl空间元件是内置的:
#输入位置,tiles,缩放比例
stamen =folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner',zoom_start=13)
stamen.create_map(path='stamen_toner.html')#保存图片
Folium也支持Cloudmade 和 Mapbox的个性化定制地图元件,只需简单地传入API_key :
custom =folium.Map(location=[45.5236, -122.6750], tiles='Mapbox',
API_key='wrobstory.map-12345678')
最后,Folium支持传入任何与Leaflet.js兼容的个性化地图元件:
tileset= r'http://{s}.tiles.yourtiles.com/{z}/{x}/{y}.png'
map =folium.Map(location=[45.372, -121.6972], zoom_start=12,
tiles=tileset, attr='My DataAttribution')
地图标记
Folium支持多种标记类型的绘制,下面从一个简单的Leaflet类型的位置标记弹出文本开始:
map_1 =folium.Map(location=[45.372, -121.6972], zoom_start=12,
tiles='Stamen Terrain')
map_1.simple_marker([45.3288,-121.6625], popup='Mt. Hood Meadows')#文字标记
map_1.simple_marker([45.3311,-121.7113], popup='Timberline Lodge')
map_1.create_map(path='mthood.html')
Folium支持多种颜色和标记图标类型:
map_1 =folium.Map(location=[45.372, -121.6972], zoom_start=12,tiles='Stamen Terrain')
map_1.simple_marker([45.3288,-121.6625], popup='Mt. Hood Meadows',marker_icon='cloud') #标记图标类型为云
map_1.simple_marker([45.3311,-121.7113], popup='Timberline Lodge',marker_color='green') #标记颜色为绿色
map_1.simple_marker([45.3300,-121.6823], popup='Some OtherLocation',marker_color='red',marker_icon='info-sign')
#标记颜色为红色,标记图标为“info-sign”)
map_1.create_map(path='iconTest.html')
Folium也支持使用个性化的尺寸和颜色进行圆形标记:
map_2 =folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner',
zoom_start=13)
map_2.simple_marker(location=[45.5244,-122.6699], popup='The Waterfront')
简单树叶类型标记
map_2.circle_marker(location=[45.5215,-122.6261], radius=500,
popup='Laurelhurst Park',line_color='#3186cc',
fill_color='#3186cc')#圆形标记
map_2.create_map(path='portland.html')
Folium有一个简便的功能可以使经/纬度悬浮于地图上:
map_3 =folium.Map(location=[46.1991, -122.1889], tiles='Stamen Terrain',zoom_start=13)
map_3.lat_lng_popover()
map_3.create_map(path='sthelens.html')
Click-for-marker功能允许标记动态放置:
map_4 =folium.Map(location=[46.8527, -121.7649], tiles='Stamen Terrain',zoom_start=13)
map_4.simple_marker(location=[46.8354,-121.7325], popup='Camp Muir')
map_4.click_for_marker(popup='Waypoint')
map_4.create_map(path='mtrainier.html')
Folium也支持来自Leaflet-DVF的Polygon(多边形)标记集:
map_5 =folium.Map(location=[45.5236, -122.6750], zoom_start=13)
map_5.polygon_marker(location=[45.5012,-122.6655], popup='Ross Island Bridge',fill_color='#132b5e', num_sides=3,radius=10)#三边形标记
map_5.polygon_marker(location=[45.5132,-122.6708], popup='Hawthorne Bridge',fill_color='#45647d', num_sides=4,radius=10)#四边形标记
map_5.polygon_marker(location=[45.5275,-122.6692], popup='Steel Bridge',fill_color='#769d96', num_sides=6, radius=10)#四边形标记
map_5.polygon_marker(location=[45.5318,-122.6745], popup='Broadway Bridge',fill_color='#769d96', num_sides=8,radius=10) #八边形标记
map_5.create_map(path='bridges.html')
Vincent/Vega标记
Folium能够使用vincent 进行任何类型标记,并悬浮在地图上。
buoy_map= folium.Map(location=[46.3014, -123.7390], zoom_start=7,
tiles='StamenTerrain')
buoy_map.polygon_marker(location=[47.3489,-124.708], fill_color='#43d9de',radius=12, popup=(vis1, 'vis1.json'))
buoy_map.polygon_marker(location=[44.639,-124.5339], fill_color='#43d9de',radius=12, popup=(vis2, 'vis2.json'))
buoy_map.polygon_marker(location=[46.216,-124.1280], fill_color='#43d9de',radius=12, popup=(vis3, 'vis3.json'))
GeoJSON/TopoJSON层叠加
GeoJSON 和TopoJSON层都可以导入到地图,不同的层可以在同一张地图上可视化出来:
geo_path= r'data/antarctic_ice_edge.json'
topo_path= r'data/antarctic_ice_shelf_topo.json'
ice_map= folium.Map(location=[-59.1759, -11.6016],tiles='Mapbox Bright', zoom_start=2)
ice_map.geo_json(geo_path=geo_path)#导入geoJson层
ice_map.geo_json(geo_path=topo_path,topojson='objects.antarctic_ice_shelf')#导入Toposon层
ice_map.create_map(path='ice_map.html')
分布图
Folium允许PandasDataFrames/Series类型和Geo/TopoJSON类型之间数据转换。Color Brewer 颜色方案也是内建在这个库,可以直接导入快速可视化不同的组合:
importfolium
importpandas as pd
state_geo= r'data/us-states.json'#地理位置文件
state_unemployment= r'data/US_Unemployment_Oct2012.csv'#美国失业率文件
state_data= pd.read_csv(state_unemployment)
#LetFolium determine the scale
map =folium.Map(location=[48, -102], zoom_start=3)
map.geo_json(geo_path=state_geo,data=state_data,
columns=['State', 'Unemployment'],
key_on='feature.id',
fill_color='YlGn',fill_opacity=0.7, line_opacity=0.2,
legend_name='Unemployment Rate(%)')
map.create_map(path='us_states.html')
基于D3阈值尺度,Folium在右上方创建图例,通过分位数创建最佳猜测值,导入设定的阈值很简单:
map.geo_json(geo_path=state_geo,data=state_data,
columns=['State', 'Unemployment'],
threshold_scale=[5, 6, 7, 8, 9,10],
key_on='feature.id',
fill_color='BuPu',fill_opacity=0.7, line_opacity=0.5,
legend_name='Unemployment Rate(%)',
reset=True)
map.create_map(path='us_states.html')
‘陆’ 直译式计算机程序设计语言Python 2.7 Release
Python ,是一种面向对象、直译式计算机庆简程序 设计 语言,也是一种功羡拿能强大而完善的通用型语言,已经具有十多年的发展历史,成熟且稳定。这种语 言具有非常简捷而清晰的语法特点,适合完成各种高层任务,几乎可以在所有的操作系统中运行。目前誉派裤,基于这种语言的相关技术正在飞速的发展,用户数量 急剧扩大,相关的资源非常多。
Python 2.7 is scheled to be the last major version in the 2.x series before it moves into an extended maintenance period. This release contains many of the features that were first released in Python 3.1. Improvements in this release include: