利用Pandas索引和选取数据方法详解
作者:wdc 发布时间:2023-04-30 23:30:07
我们将使用2019年全国新能源汽车的销量数据作为演示数据,数据保存在一个csv文件中,读者可以在GitHub仓库下载到 https://github.com/pythonlibrary/practice-pandas-skills.git
本篇文章中会使用到两个库pandas 和 numpy,确保它们都正确的安装,而工作环境则使用jupyter notebook,如果有需要学习如何搭建环境的,可以阅读 数据科学家的一种工作环境 – virtualenv和Jupyter Notebook。
文章中用于演示的代码也可以在前边提到的GitHub仓库中找到对应的notebook源文件,文件名为 index_select_data.ipynb
首先在notebook中导入pandas和numpy,按照常用习惯,pandas导入为pd,numpy导入为np
import pandas as pd
import numpy as np
1. 导入数据集
在这一节中,我们会将数据文件导入为pandas中的数据对象,同时针对这个数据对象,做一些基本的信息展示,方便我们理解我们将要工作的数据。
我们的原始数据文件为csv格式,因此可以快速的使用pandas提供的read_csv方法将csv文件导入为pandas的DataFrame,同时利用DataFrame对象的head方法查看前两行数据的内容。
df = pd.read_csv('NEV_sales.csv')
df.head(2)
head方法接收一个整数为参数,代表,我们想要获得的行数,默认为5行,这里我们获得了2行,可以看出,数据的索引(index)是数字,列(column)里边包含了品牌以及2019年从1月份到12月份的销售量。
为了后边演示,我们将利用df这个数据集再创建一个新的数据集名为df_brand_index,它跟df的区别是,它将使用品牌(brand)作为索引,列为2019年从1月份到12月份的销售量。我们使用set_index方法来实现。这次,我们使用跟head方法相对应的tail方法来查看df_brand_index和df的不同。
df_brand_index = df.set_index('brand')
df_brand_index.tail(2)
可以看出,输出的第一列名称brand相比其他列名称向下移了一点,它已经变成了索引,跟原来的索引不同,它具有索引名,即brand,但是所支持的操作方法跟索引是一致的。
另外,在输出中我们看到了两个有趣的信息,一是,最后一行品牌为总计,这表明我们的原始数据中最后一行是所有行的总计,在真正的数据分析中,它肯定会对结果有不好的影响,因此可以排除掉,而本文侧重于pandas的操作,因此它对我们没影响,二是,奔驰品牌在2019年每个月的销量都是NaN,NaN是pandas中的一个特殊值,代表缺失值,而在我们这个数据集中,其实也就是销量为0。
接下来我们从3个方面简单的看看我们的数据。
首先是数据量,我们正在分析多大的量的数据呢,DataFrame的shape属性会告诉我们数据有多少行,多少列。通过下述代码获取到df_brand_index和df的形状。
df_brand_index.shape, df.shape
对于df,总过有77行,15列,而df_brand_index有77行,14列因为我们将品牌列转换为了索引,所以少了一列。
然后是数据类型,我们的数据中是否有一些非法数据类型,我们分析的是新能源车销量,因此,期望所有的数据都是数字,而非字符串或者其他,DataFrame的dtypes属性会告诉我们这样的信息。
df_brand_index.dtypes
没问题,所有的列都是数字(因为类型都是float64),如果有任一列出现了 object字样,那就是说该列包含非数字的内容。
最后是销售量的基本信息,例如每个月的销售量的最大,最小,平均值等等,使用DataFrame的describe()方法可以或者到这些信息。
df_brand_index.describe()
比如,2019年11月,新能源车在所有品牌的平均销量为3831台,最大为72795台(不合理,对吧?),为什么呢,记得我们前边使用了tail方法看到数据的最后一行为总计,因此这个最大值其实就是总计的值。
2. 列选择
我们尽量避免使用列索引的称呼,因为如果看英文文档的话,pandas并不使用column index来称呼列,而是直接使用column,如果称呼列索引的话恐怕会带来歧义。
通过方括号[]可以从DataFrame获取到某一列或者某几列的数据。这里注意:如果我们获取多列的数据,则得到的仍然是一个DataFrame,而如果我们仅获取一列数据,将会得到一个Series(跟DataFrame同一等级的pandas对象,也是pandas中的另外一种常用的数据结构)
sr_brand_index = df_brand_index['2019-11']
sr_brand_index.head(2)
上边,我们获取了2019年11月的销量数据,查看内容发现,索引名称还是为品牌,但是列没有了名称。
而下方,我们获取了2019年11月和12月两个月的销量数据,查看内容发现,不仅索引名称在,同样的DataFrame具有两列,分别对应两个月的数据。
df_brand_index[['2019-12', '2019-11']].head(2)
3. 行选择
这一节,我们将按行来选择数据。在pandas中最常用的,也是官方推荐的两种进行列选择的方法为loc和iloc,两者比较容易混淆,这里按照官方方法提供一个简单的快速记忆方法loc代表location,使用标签来定位, 而iloc中的i解读为integer,即integer location通过数字来定位。什么意思呢?看下边对比。
数字Index
首先我们使用df这个DataFrame,还记得吧,这个对象使用数字作为index,索引,我们来使用loc获取index标签从0到4的行:
df.loc[0:4]
我们最终得到了5行内容,而index为从0到4.
然后,我们来使用iloc获取index从位置0到位置4的行:
df.iloc[0:4]
这里大家发现了区别,我们仅仅得到了4行,index为从0到3,为什么呢,iloc代表利用整数编号来获取,其行为类似于python内置数据结构list的操作方法,获取到的结果为[0,4)。
到这里,或许读者已经有点晕了,别着急,看过下边这个例子以后,你就会恍然大悟,并明白为什么loc和iloc有时候很容易混淆。
字符串Index
我们再在df_brand_index上边使用loc和iloc来看看效果,还记得吧df_brand_index中的Index是品牌名称。
加入向上边一样,使用df_brand_index.loc[0:4]来获取前5行,那么我们会得到一个异常
为什么呢?因为loc是使用标签来做选择,而这个数据集的Index标签为字符串而不是数字,正确的用法为:
df_brand_index.loc['北京':'宝骏']
然后iloc的用法就很容易理解并且显而易见了。
df_brand_index.iloc[0:4]
4. 行+列选择,找到元素
避免混淆,我们将继续使用df_brand_index来做演示。假如说现在我们想找到某北汽品牌在2019年11月的销量,或者前5个品牌在2019年10月到12月的销量,我们就需要结合行列来一起进行选择,pandas会智能的根据找到的元素的形状返回相应的数据类型,例如:
获取北汽2019年11月的销量
df_brand_index.loc['北京', '2019-11']
如果使用iloc方法,下边的方法可已得到等价的结果
df_brand_index.iloc[0, 1] # 1st column is 2019-11 in df_brand_index
获取前5个品牌从2019年10月到12月的销量
df_brand_index.loc['北京':'宝骏', '2019-12':'2019-10']
类似的使用iloc方法,下边的方法也可以得到等价的结果
df_brand_index.iloc[0:5, 0:3]
5. 条件选择
另外一个常用的数据选择筛选办法是根据元素的内容,比如,我们想获取到2019年11月和12月销量均大于3000台的品牌数据。
df_brand_index[(df_brand_index['2019-12'] > 3000) & (df_brand_index['2019-11'] > 3000)]
这里,我们使用了pandas的布尔选择功能,即在[]中提供一个布尔条件,(df_brand_index[‘2019-12'] > 3000) & (df_brand_index[‘2019-11'] > 3000)代表,11月和12月销量均大于3000,只得特别注意的是,条件中的括号非常重要,是一定需要使用的,否则,pandas将抛出异常。
6. 查找元素位置
最后,在实际项目中还会有需要通过某一个元素的值来寻找它在数据中出现的位置,例如我们想知道2019年11月销量为6046的品牌,或者我们想知道在整个DataFrame中销量为6046的所有品牌和对应的月份
在已知列中查找
如果我们想知道2019年11月销量为6046的品牌,我们完全可以使用第五节中的条件选择先选取到相应的数据,然后再使用DataFrame的index属性得到其对应的品牌。
df_brand_index[df_brand_index['2019-11']==6046].index
在整个DataFrame中查找
如果我们想知道在整个DataFrame中销量为6046的所有品牌和对应的月份,那么pandas提供的内建方法就无法满足这个要求了,我们可以借助numpy来快速实现。
numpy提供了where方法,它可以返回满足条件的元素在输入的numpy arry的行列位置编号,通过位置编号就可以在DataFrame中获取到品牌。
DataFrame中有一个to_numpy方法,可以将DataFrame转换为numpy array,将两部分连起来,就可以获得index和column的编号。
idx = np.where(df_brand_index.to_numpy()==6046)[0][0]
col = np.where(df_brand_index.to_numpy()==6046)[1][0]
idx, col
上边代码会输入(2,1)。其中2为index的编号,1为column编号,对应于df_brand_index中为:
来源:https://pythonlibrary.net/2020/03/14/index-select-data-in-pandas-dataframe/
猜你喜欢
- 一、技术路线requests:网页请求BeautifulSoup:解析html网页re:正则表达式,提取html网页信息os:保存文件imp
- 当需要远程办公时,使用pycharm远程连接服务器时必要的。PyCharm提供两种远程调试(Remote Debugging)的方式:配置远
- Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x、纵轴为y的坐标系原点,(0,0)
- python读取pdf文档一、 准备工作安装对应的库pip install pdfminer3kpip install pdfminer.s
- golang判断元素是否在数组内众所周知,golang里没有像python的in来判断元素是否在list里存在,可替代的办法是将list放到
- pycharm from lxml import etree标红##原因:没有lxml这个包###解决方法:需要安装xlml包####下载地
- 1.MySQL官网下载压缩版文件,放至安装路径下载zip安装包MySQL :: Download MySQL Community Serve
- 本文实例讲述了Python面向对象之私有属性和私有方法。分享给大家供大家参考,具体如下:01. 应用场景及定义方式应用场景在实际开发中,对象
- 每次写博客都是源于纳闷,python解析pcap这么常用的例子网上竟然没有,全是一堆命令行执行的python,能用吗?玩呢?pip安装sca
- 前言 Javascript是一门很自由的语言,在JS里,里面一切的东西都是变量.包括函数在内. 基础 函数 (定义)(参数1[,参数2..]
- 昨天在做mergeCSS的时候遇到两个正则匹配的问题,也花了不少的时间,最后在CSS森林群的 CE 同学帮助下,才完成了这俩正则,特别记录下
- 在JavaScript中存在这样两种原始类型:Null与Undefined。这两种类型常常会使JavaScript的开发人员产生疑惑,在什么
- 在数据处理过程中比如从CSV文件中导入数据data_df = pd.read_csv("names.csv")在处理之前
- 备注:Oracle 19C一. Json数据存储看了下官网,Json数据一般使用varchar2(400),varchar2(32676)或
- 1. 使用 length 属性追加元素使用length属性,可以在数组末尾后面添加一个元素var arr = [1, 2, 3, 4, 5]
- 介绍在操作数据帧时,初学者有时甚至是更高级的数据科学家会对如何在pandas中使用inplace参数感到困惑。更有趣的是,我看到的解释这个概
- 支付宝十年账单上的数字有点吓人,但它统计的项目太多,只是想看看到底单纯在淘宝上支出了多少,于是写了段脚本,统计任意时间段淘宝订单的消费情况,
- 制作一个查看器可以查看豆瓣前100名电影的信息,当然这个爬取信息比较简单。所以重点放在 QThread 多线程的应用上面。QThread 子
- MFCC梅尔倒谱系数(Mel-scaleFrequency Cepstral Coefficients,简称MFCC)。MFCC通常有以下之
- 目录简介使用介绍实际体验小结简介MySQL 作为最流行的开源数据库,在各个领域都有相当广泛的应用,作为一个 MySQL DBA,经常会对数据