Python利用Groupby机制绘制柱状图时KeyError和TypeError问题及解决方法

出现的四种问题

1)在使用groupby机制中apply()函数括号内必须是函数名,而不能是方法名,需要将方法包装成函数;
2)通过unstack()方法将数据转换成表格形式,方便进行索引和操作;
3)在使用Seaborn绘图时,对分组索引出现的KeyError问题的解决;
4)在对柱状图加说明时,遇到的typeError问题的解决方法

在该主题下进行柱状图绘制时需要对数据进行分箱操作,需要用到pandas的cut和qcut工具,groupby方法,及seaborn的barplot方法,以下将我在操作过程中遇到的问题及其解决方法进行总结,供参考:

1 我们在使用groupby方法时,通常要对数据进行拆分-应用-联合操作,而其中对数据应用apply方法是将拆分的数据调用函数,在apply()括号内必须是函数名,不能是方法名,因此,我们需要将我们要使用的方法包装成函数,再代入到apply()

def get_stats(group):
    return {'count':group.count()}
data=pd.read_csv('c:/Users/dell/Desktop/a16.csv')
quartiles=pd.cut(data['VF'],4)
grouped=data['VF'].groupby(quartiles)
data_sum=grouped.apply(get_stats).unstack()

这里可以发现在开头先定义一个函数,这个函数的目的就是将count方法包装成函数,方便调用;如果这里不这样做,而是直接将count带入apply中,如下:

data=pd.read_csv('c:/Users/dell/Desktop/a16.csv')
quartiles=pd.cut(data['VF'],4)
grouped=data['VF'].groupby(quartiles)
data_sum=grouped.apply(count).unstack()

输出结果如下图:在这里插入图片描述报错信息是NameError,name ‘count’ is not defined,所以,这里需要注意,apply()括号中一定填入的是函数名,而不是方法名,除了函数名外,如果有其他要求,也可以在)函数名后增加别的参数或者关键字;
2 我们注意到:

data_sum=grouped.apply(get_stats).unstack()

这里的unstack起到的作用就是将data_sum转换呈列表形式,如果这里不适用unstack(),我们获得的输出形式如下图:
在这里插入图片描述
如果我们使用unstack()时,输出形式转变为:
在这里插入图片描述转换成列表方便我们对数据的索引;
3 采用data_sum数据进行绘图时,代码如下:

data_sum.to_csv('c:/Users/dell/Desktop/data_sum.csv')
data_sum.plot()
plt.xlabel('VF range')
plt.ylabel('Number')
plt.title('The statistic of VFdistribution')
sns.barplot(x=data_sum['VF'],y='count',data=data_sum)
plt.legend()
plt.show()

我们发现sns.barplot(x=data_sum[‘VF’],y=‘count’,data=data_sum),如果这样,我们得到的结果将会是:KeyError:‘VF’
在这里插入图片描述
如果我们将代码改写为:

sns.barplot(x=data_sum.index,y='count',data=data_sum)

则上述的错误就会消失,通过debug发现,data_sum[‘VF’]没有办法进行输出,即使使用data_sum.loc[:,‘VF’]同样会报错KeyError;

尝试使用data_sum.iloc[:,0]进行输出,但是获得的结果是:
在这里插入图片描述
以上结果与直接输出data_sum的结果就差一个列名count,如图所示:
在这里插入图片描述
但是data_sum.index输出的结果是:
在这里插入图片描述
通过以上输出对比,可以发现索引该位置的索引列并不能通过索引名称‘VF’输出,需要通过
通过以上的代码,我们就可以获得一副下述图片
在这里插入图片描述
4 如果想在每个柱状图上方都明确的标识数据的数量,可以使用plt.text()函数,但是在使用过程中需要注意必须把很坐标转换呈数字而不能用目前的索引,因为在plt.text()函数中有必选参数有x表示x坐标位置,y表示y坐标位置,即通过两个坐标确定需要引入的字符的位置,s是输入的字符串显示的内容,这三项是必须规定的参数,其中x和y必须是字符串或者数字,不能是这种(1.45,1.486]间隔,如果我们依然按照之前的代码:

def get_stats(group):
    return {'count':group.count()}
data=pd.read_csv('c:/Users/dell/Desktop/a16.csv')
quartiles=pd.cut(data['VF'],4)
print(quartiles)
grouped=data['VF'].groupby(quartiles)
data_sum=grouped.apply(get_stats).unstack()
print(data_sum)
data_sum.to_csv('c:/Users/dell/Desktop/data_sum.csv')
data_sum.plot()
plt.xlabel('VF range')
plt.ylabel('Number')
plt.title('The statistic of VF distribution')
sns.barplot(x=data_sum.index,y='count',data=data_sum)
for x,y in zip(data_sum.index,data_sum['count']):
    plt.text(x,y,
             int(y),
             ha='center',
             va='bottom',
             fontsize=12,
             color='r')
plt.legend()
plt.show()

会出现报错信息:
在这里插入图片描述
最后一行可以发现是TypeError:float()argument must be a string or number,not ‘pandas._libs.interval.Interval’;基本意思就是x坐标位置不能是间隔(1.45,1.486],必须是数字或者字符串,因此,我们需要将代码做个小改动,把

quartiles=pd.cut(data['VF'],4)

改为

quartiles=pd.cut(data['VF'],4).cat.codes

效果就是将间隔转换成对应间隔从小到大的数字,
在这里插入图片描述
总的代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
import csv
import seaborn as sns 
from numpy import nan as NA 
from pandas import DataFrame
from pandas import read_csv
def get_stats(group):
    return {'count':group.count()}
data=pd.read_csv('c:/Users/dell/Desktop/a16.csv')
quartiles=pd.cut(data['VF'],4).cat.codes
print(quartiles)
grouped=data['VF'].groupby(quartiles)
data_sum=grouped.apply(get_stats).unstack()
print(data_sum)
data_sum.to_csv('c:/Users/dell/Desktop/data_sum.csv')
data_sum.plot()
plt.xlabel('VF range')
plt.ylabel('Number')
plt.title('The statistic of VF distribution')

sns.barplot(x=data_sum.index,y='count',data=data_sum)

for x,y in zip(data_sum.index,data_sum['count']):
    plt.text(x,y,
             int(y),
             ha='center',
             va='bottom',
             fontsize=12,
             color='r')
plt.legend()
plt.savefig('Desktop/barplot.png'')
plt.show()

输出的图片如下所示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr Pydaty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值