需求:我想等频分箱,就是比如一个score有不同的分数,先按照分数升序排列,排列后按照人数的分位数进行分箱,最终实现下图效果
数据下载链接网址https://bbs.pinggu.org/forum.php?mod=viewthread&tid=9485342&extra=
解答:
#------------------------------------------------------------ #导入数据 #-------------------------------------------------------------- import pandas as pd import numpy as np data1=pd.read_excel("D:\\forver.xlsx")
#计算分位数 0.2。。。,设定分箱区间 qq=data1["score1"].quantile([0.2,0.4,0.6,0.8]) min1=data1["score1"].min() max1=data1["score1"].max() intervel=[0]+list(qq)+[max1]
#对变量进行排序 data1.sort_values(by="score1",ascending=True,inplace=True) #对相关变量进行分箱 data1["score1分箱l"]=pd.cut(data1.score1,intervel) data1["score1分箱"]=pd.cut(data1.score1,intervel,labels=[1,2,3,4,5])
#--------------------------------------------------------------- # 准备画图用数据 #----------------------------------------------------------------- #统计各箱包含的样本个数 #计算各箱的bad% #说明target取值为1则为bad,0为good score1各箱人数=data1["score1分箱l"].value_counts() score1各箱人数.sort_index(inplace=True) score1badcount=data1[data1["target"]==1]["score1分箱l"].value_counts() score1goodcount=data1[data1["target"]==0]["score1分箱l"].value_counts() #将几个指标按照索引进行横向合并 picdata=pd.concat([score1各箱人数,score1badcount,score1goodcount],axis=1) picdata.columns=["score1各箱人数","score1badcount","score1goodcount"] #计算各箱的bad% picdata["badper"]=picdata["score1badcount"]/picdata["score1各箱人数"] #
#--------------------------------------------------------------- # 画图 #------------------------------------------------------------------- xticklabel=[] for i in range(len(intervel)-1): print(i) tt=str(int(intervel[i]))+"-"+str(int(intervel[i+1])) print(tt) xticklabel.append(tt) import matplotlib.pyplot as plt #解决中文乱码问题 plt.rcParams['font.sans-serif'] = ['Simhei'] fig,ax1=plt.subplots() ax1.bar(xticklabel,picdata["score1各箱人数"],label="坏人数",color='r',width=0.6) ax1.bar(xticklabel,picdata["score1goodcount"],label="好人数",color='b',width=0.6) ax1.set_ylim([0,300]) # y轴边界 ax1.legend(loc=2) ax2=ax1.twinx() ax2.plot(np.arange(5),picdata["badper"],'r',label="bad百分比") ax2.set_ylim([0,1]) # y轴边界 ax2.legend(loc=1) ax1.set_xticklabels(xticklabel,fontsize=20,rotation=45) fig.suptitle(u'score1的情况',fontsize=15)








比如说我想用,'font.sans-serif'下的'Arial'这个字体,但是我这么改写代码后:
plt.rcParams['font.sans-serif'] = ['Arial']
运行会报错,是为什么呢?

问:柱状图及折线图的颜色可以更改吗?
答:我在下面这个帖子里回答了下
https://www.pinggu.com/post/details/5f3b5338922c1e31e64917fd

问:
plt.rcParams['font.sans-serif'] = ['Simhei']
请问这里面字体可以改吗?
答:
https://www.pinggu.com/post/details/5f3b4fb0922c1e31e64917f8

plt.rcParams['font.sans-serif'] = ['Simhei']
请问这里面字体可以改吗?柱状图及折线图的颜色可以更改吗?

问:
您好,可以请教下,如果0一个箱子,1一个箱子,2一个箱子,这种情况,代码怎么写呢
答: 比如你的数据中score5这一列就是你说的这种情况,这种情况不需要分箱,直接看每个值出现的频数就行。 用下面的命令。
score5各箱人数=data1["score5"].value_counts() score5各箱人数.sort_index(inplace=True)
score5badcount=data1[data1["target"]==1]["score5"].value_counts() score5goodcount=data1[data1["target"]==0]["score5"].value_counts() #将几个指标按照索引进行横向合并 picdata5=pd.concat([score5各箱人数,score5badcount,score5goodcount],axis=1) picdata5.columns=["score5各箱人数","score5badcount","score5goodcount"] #计算各箱的bad% picdata5["badper"]=picdata5["score5badcount"]/picdata5["score5各箱人数"]
import matplotlib.pyplot as plt
#解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Simhei']
fig,ax1=plt.subplots()
#[0,1,2]是横轴的刻度线标签
ax1.bar([0,1,2],picdata5["score5各箱人数"],label="坏人数",color='r',width=0.6)
ax1.bar([0,1,2],picdata5["score5goodcount"],label="好人数",color='b',width=0.6)
ax1.set_ylim([0,600]) # y轴边界
ax1.legend(loc=2)
ax2=ax1.twinx()
ax2.plot(picdata5["badper"],'r',label="bad百分比")
ax2.set_ylim([0,1]) # y轴边界
ax2.legend(loc=1)
fig.suptitle(u'score5的情况',fontsize=15)

问:
还有个关于等频分箱的问题想请教您:如果x变量里面有空值和0,0在这里面也是有意义的值,并且空值和0的比例占比较大,这种情况下还可以用等频分箱吗?如果想继续用等频分箱,要对数据如何处理呢
答:
1.如果你的数据的取值比较少的话比如0值占了50%,1占了20%,2占了30%,也就是说数据取值个数比较少,那你直接画频数图就行,不用分箱了,因为本身就算是几个箱子,0是一个箱子,1是一个箱子,2是一个箱子。
2.如果你的 数据的取值比较多的话比如0值占了50%,而其他值的取值区间为1-100,你可以将0值单独作为一类,其他值再进行分箱画图

还有个关于等频分箱的问题想请教您:如果x变量里面有空值和0,0在这里面也是有意义的值,并且空值和0的比例占比较大,这种情况下还可以用等频分箱吗?如果想继续用等频分箱,要对数据如何处理呢

问:ax2=ax1.twinx()#产生一个ax1的镜面坐标 ax2.plot(np.arange(5),picdata["badper"],'r',label="bad百分比")#第一个参数是横轴的刻度线标签
这两行代码的作用是添加了折线图对吧,这块python是怎么识别出来是折线图的呢,还是这个plot函数自动生成的就是折现图?谢谢!
答:是的ax2.plot就是画折线图,ax1.bar就是画柱形图

问:score1各箱人数.sort_index(inplace=True)
这步是做什么用呢?
答:作用是对score1序列进行排序,排序前是这样的
排序后
inplace=True的意思是直接作用于score1各箱人数,而不是临时排序。

ax2=ax1.twinx()#产生一个ax1的镜面坐标 ax2.plot(np.arange(5),picdata["badper"],'r',label="bad百分比")#第一个参数是横轴的刻度线标签
这两行代码的作用是添加了折线图对吧,这块python是怎么识别出来是折线图的呢,还是这个plot函数自动生成的就是折现图?谢谢!

问题框1:
fig,ax1=plt.subplots()
这个的意思是生成一张图纸fig,和一个坐标系ax1。
问题框2:
ax1.legend(loc=2) 是给坐标系ax1添加图例,loc参数用于设定添加图例的位置。数值意思如下
and each "string" locations can also be given as a
numeric value:
=============== =============
Location String Location Code
=============== =============
'best' 0
'upper right' 1
'upper left' 2
'lower left' 3
'lower right' 4
'right' 5
'center left' 6
'center right' 7
'lower center' 8
'upper center' 9
'center' 10
=============== =============
问题框3:
ax2.plot(np.arange(5),picdata["badper"],'r',label="bad百分比")
里面的第一个参数是横轴的刻度线标签,你可以把这个刻度线标签直接设定为
ax2.plot(xticklabel,picdata["badper"],'r',label="bad百分比")
问题框4:
ax2.legend(loc=1)
给坐标系ax2添加图例
问题框5:
ax1.set_xticklabels(xticklabel,fontsize=20,rotation=45)
设定横轴刻度线标签的字号为20,旋转45度,是怕标签太长,然后多个标签可能会重叠在一起。

先看下intervel里面的内容是什么样的
然后生成一个空白列表
xticklabel=[]
然后通过循环给空白列表xticklable添加元素。下面的循环是一个整体,一定不要分开去运行。
这是一个完整的循环,经过这一次循环,xticklabe列表就会追加一个元素,执行完上面的命令再看下xticklabel
xticklabel
Out[111]: ['0-5', '5-7', '7-11', '11-17', '17-46']
生成这个列表是为了画图的时候,将这个列表作为横轴的刻度标签使用。