美文网首页
Pandas从入门到精通(3)- Pandas索引

Pandas从入门到精通(3)- Pandas索引

作者: 木头里有虫911 | 来源:发表于2021-01-03 21:20 被阅读0次

首先我们要明确索引的作用。在SQL中我们通过索引能够快速的定位数据,就像一本书的目录一样,通过目录我们可以快速的定位到书中的某个章节。在pandas里面,我们通过索引进行数据的选取和筛选。就像在一张大表里面选取我们需要分析或者感兴趣的内容,此时就需要用到索引的相关操作。这个是pandas中基本操作,需要熟练掌握。因为一维的Series比较简单,我们以二维的数据结构DataFrame为例进行总结。主要包括以下内容:

  1. 列选取,选取一列或者多列
  2. 行选取
  3. loc和iloc选取(主要内容,经常用)
  4. Query方法选取

下面通过代码实战进行演练。下面代码中涉及的数据集和代码可以在后台回复“pandas”获取

import numpy as np
import pandas as pd

df = pd.read_csv('learn_pandas.csv')
df.head()
image.png

这是一个包含学生姓名/性别和学校以及身高体重等信息的表格

1.列选取:根据要求选择一列或者多列

对于DataFrame的列,可以使用“[]”操作符或者"."进行选择,使用“.”时要注意,列明不能有空格如下:

# 通过列标签选择数据
df['School'].head()
>>>
0    Shanghai Jiao Tong University
1                Peking University
2    Shanghai Jiao Tong University
3                 Fudan University
4                 Fudan University
Name: School, dtype: object

要同时选取多列时,一般是先创建一个列表,将所需要的内容放入列表中,再将该列表整体传入df中:

use_col = ['Name', 'Gender', 'Height', 'Test_Date']
df[use_col].head(5)

结果如下:

image.png

2. 行选取

当要求按照某个字段的条件筛选某些行时,可以直接将该条件作为一个condition传入df中,举例:

  1. 筛选 Peking University的学生:
# 直接按照条件带入带入:
df[df['School'] == 'Peking University'].head()
# 上面的写法等价于:
condition = (df['School'] == 'Peking University')
df[condition].head
>>>

结果如下:


image.png
  1. 筛选身高大于165的同学:
df[df['Height'] > 165].head()
image.png

3. loc和iloc

在实际实战中,按照一定条件选择数据更常用的方法是loc和iloc, 两者的语法结构类似,不同之处在于:

  • loc : 基于label索引器,列名和行号都可以作为label
  • iloc: 基于index索引的索引器
    这两个容易混淆,实际中可以按照首字母记忆,即loc和label都是“l”开头,iloc和index都是“i”开头。
    语法结构以loc为例,iloc一样:
    df. loc[*, *] ,其中第一个 * 代表行的选择,第二个 * 代表列的选择,如果省略第二个位置写作 loc[] ,这个 * 是指行的筛选。
    其中, * 的位置一共有五类合法对象,分别是:单个元素、元素列表、元素切片、布尔列表以及函数,常用的为前面4个,下面将依次说明。
    我们以loc为例,前面说了,loc是基于label选取的,我们把行索引index设置为Name,这样更容易说明。
df_new = df.set_index('Name')
df_new.head()
image.png

【a】 * 为单个元素

此时,直接取出相应的行或列,如果该元素在索引中重复则结果为 DataFrame,否则为 Series

df_new.loc['Gaojuan You'] #   原表格中只有一行满足条件,返回一个Series
>>>
School         Fudan University
Grade                 Sophomore
Gender                     Male
Height                    174.0
Weight                     74.0
Transfer                      N
Test_Number                   2
Test_Date             2019/11/6
Time_Record             0:05:22
Name: Gaojuan You, dtype: object
df_new.loc['Qiang Sun']  # 原表格中有多行满足条件,返回一个DataFrame 
image.png

【b】 * 为元素列表

此时,取出列表中所有元素值对应的行或列:

df_new.loc[['Qiang Sun', 'Xiaojuan Sun'],['School', 'Gender', 'Weight']]
image.png

【c】 * 为切片

之前的 Series 使用字符串索引时提到,如果是唯一值的起点和终点字符,那么就可以使用切片,并且包含两个端点,如果不唯一则报错:

df_new.loc['Changqiang You':'Gaoqiang Qian', 'School':'Test_Number']
image.png

【d】 * 为布尔列表
在前面的行选取中,其实我们已经使用了和loc布尔列表类似的操作了。我们在来看一下上面例子中的表达式: df[df['Height'] > 165],在该表达式中:

  • 第一步:内部的“df['Height'] > 165” 返回一个与 DataFrame 长度相同的布尔列表
  • 第二步:外面在套上df后,实际上执行了一个筛选操作,即且列表为 True 的位置所对应的行会被选中, False 则会被剔除。
    df.loc也可以完成相同的功能:
(df.loc[df['School'] == 'Tsinghua University' ]) == (df[df['School'] == 'Tsinghua University'])
image.png

在实际操作中,往往需要根据多个条件来选取数据,对于这种复合条件而言,可以用 |(或), &(且), ~(取反) 的组合来实现。
实战操作: 选取复旦大学中体重超过70kg的大四学生,或者北大男生中体重超过80kg的非大四的学生:

condition_1_a = df_new['School'] == 'Fudan University'
condition_1_b = df_new['Grade'] == 'Senior'
condition_1_c = df_new['Weight'] > 70
condition_1 = condition_1_a & condition_1_b & condition_1_c

condition_2_a = df_new.School == 'Peking University'
condition_2_b = df_new.Grade == 'Senior'
condition_2_c = df_new.Weight > 80
condition_2 = condition_2_a & (~condition_2_b) & condition_2_c

res = df_new.loc[condition_1 | condition_2]
res

结果如下:


image.png

iloc 的使用与 loc 完全类似,只不过是针对index索引进行筛选,因为行/列的索引index均是从0开始的整数,因而在相应的 * 位置处一共也有五类合法对象,分别是:整数、整数列表、整数切片、布尔列表以及函数,函数的返回值必须是前面的四类合法对象中的一个,其输入同样也为 DataFrame 本身。
这个方法有一个常用的场景,就是在机器学习的数据集划分中。例如在一个大表中,前面的列为特征,最后一列为对应的标签,这时需要将除去最后一列的数据作为X,最后一列的值作为标签Y,例如在上面的表格中,我们可以:

X = df.iloc[:, :-1] # : 前面为行,不写表示选取所有行,后面为列,-1为最后一列,不包括
Y = df['Time_Record'] 

4. Query方法

在 pandas 中,支持把字符串形式的查询表达式传入 query 方法来查询数据,其表达式的执行结果必须返回布尔列表。在进行复杂索引时,由于这种检索方式无需像普通方法一样重复使用 DataFrame 的名字来引用列名,一般而言会使代码长度在不降低可读性的前提下有所减少。
例如,可以将上面loc方法的复合选取改用query方法来做:

# 将 loc 一节中的复合条件查询例子可以如下改写:
df.query('((School == "Fudan University")&'
          ' (Grade == "Senior")&'
        ' (Weight > 70))|'
         '((School == "Peking University")&'
         ' (Grade != "Senior")&'
         ' (Weight > 80))')
image.png

在 query 表达式中,系统自动帮用户注册了所有来自 DataFrame 的列名,所有属于该 Series 的方法都可以被调用,和正常的函数调用并没有区别,即在调用是无需在声明df['列名‘]的形式,直接使用列名。例如查询体重超过均值且性别为女的学生:

df.query('(Weight > Weight.mean())' and '(Gender == "Female")').head(6)

部分结果如下:


image.png

参考:开源内容Joyful Pandas, 作者 DataWhale耿远昊
另外,更多精彩内容也可以微信搜索,并关注公众号:‘Python数据科学家之路“ ,期待您的到来和我交流

相关文章

网友评论

      本文标题:Pandas从入门到精通(3)- Pandas索引

      本文链接:https://www.haomeiwen.com/subject/tlnrnktx.html