2020-04-19 pandas索引与数据筛选

import seaborn as sns
import pandas as pd
import numpy as np

Pandas Indexing and Selecting

让我们来讨论一下pandas数据的切片和切分(slicing and dicing),类似于R里面的数据框或矩阵取子集。今天我们将复习四个主题:

  • 复习基础知识
  • 多重索引
  • 获取单个值
  • 一些不用在意的东西

关于基础知识可以参考: basic indexing ,索引相关可参考 advanced indexing. 但要这些资料会很冗长,他会提供一些你可能都用不到的方法,或者没有必要掌握的技能,自行选择:

复习基础知识

首先,让我们简单回顾一下传统的索引和筛选(indexing and selection)。(我们在pandas基础知识pandas fundamentals中介绍了大部分内容)。首先,以下是我们将要使用的数据(旧的 tips 数据):
这个数据存放在:https://github.com/guipsamora/pandas_exercises/tree/master/07_Visualization/Tips

ls
�[31mCombining DataFrames.ipynb�[m�[m*            �[31mPandas Intro to Data Structures.ipynb�[m�[m*
�[31mGroup Operations.ipynb�[m�[m*                �[31mRow-Column Transformations.ipynb�[m�[m*
�[31mIndexing and Selecting.ipynb�[m�[m*          �[31mtips.csv�[m�[m*
�[31mMisc Functions.ipynb�[m�[m*
tips = pd.read_csv('tips.csv')
tips.head()
image.png
del tips['Unnamed: 0']
tips.head(3)
image.png

下面介绍4种方式从数据框中获取数据:

  1. 获取不同的列
# 1) get columns
tips[['total_bill', 'tip']].head()
image.png
  1. 获取不同的行
# 2) get some rows
tips[3:5]
image.png
  1. 根据行名列名获取数据
# 3) select rows and columns based on their name
tips.loc[2:4, 'sex': 'smoker']
image.png
  1. 根据位置信息获取数据
# 4) select rows and columns by their ordering
tips.iloc[1:3, 0:2]
image.png
  1. 根据逻辑值来筛选
# 5) select using a bool series
tips[tips['tip'] > 1].head()
image.png

不过这些仅仅是冰山一角。

实际上,当你深入研究pandas的其他功能(functionalities)时,你很可能会涉及到其他几个重要的概念。

Multi-index

这是一个您可能认为不需要的主题--但事实证明它是一个相当频繁的用例(usecase)。

multi-index背后的最初想法是提供一个框架来处理更高的模糊数据(从而取代panels)。
但由于一些操作,这变得相当平常。在几乎所有情况下,multi-index都来自groupby's(您几乎不会自己构建或阅读它)。

下面我们举个例子:

tips.head()
image.png
mi_tips = tips.groupby(['sex', 'smoker']).agg({'tip': 'mean'})
mi_tips
image.png
mi_tips.index
    MultiIndex([('Female',  'No'),
                ('Female', 'Yes'),
                (  'Male',  'No'),
                (  'Male', 'Yes')],
               names=['sex', 'smoker'])

最终,您可以在此类型的数据之上执行大量操作。您还可以执行等效的multi-index操作,如下所示:

mi_tips.loc[('Male', 'No')]
    tip    3.113402
    Name: (Male, No), dtype: float64

通过这种方式,你会学到很多细节,但是总会有例外。

因此,我一直以来处理这个问题的方法很简单,就是重置索引。

ri_tips = mi_tips.reset_index()
ri_tips
image.png

请注意我们现在是如何将值分布到整个column中的。因此,通过这种方式,很容易只选择不吸烟的男性(the male non-smokers):

ri_tips[(ri_tips['smoker'] == 'No') & (ri_tips['sex'] == 'Male')]
image.png

处理此问题的另一种方法是只删除某些索引:

ri0_tips = mi_tips.reset_index(level=0)
ri0_tips.loc['Yes']
image.png

然后如果再需要用到之前的索引,还可以换回来,参考pull indexes back into the index (通常这个操作使用在某些类型数据合并的过程中)。

ri_tips.set_index(['sex', 'smoker'])
image.png
ri0_tips.set_index('sex', append=True)
image.png

获取单个值

下一个索引小把戏(indexing trick)主要是关于速度的。它是在获取和设置单一的值(使用后提升计算速度)。这是一个非常简单的问题:

tips.head(3)
image.png

当需要获取/设定单个值要用到at函数

tips.at[0, 'total_bill'] = 9000
tips.head(3)
image.png
tips.iat[0, 0]
    9000.0

如果您正在修改数据框的单个值,则应该始终使用这些工具。它速度更快,而且是知道您没有搞砸的好方法(经常修改数据可能会导致奇怪的错误)。

所以,为了证明它更快,我们来计时吧!

%%timeit
tips.at[0, 'total_bill'] = 6
6.12 µs ± 46.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
tips.loc['total_bill', 0] = 6
272 µs ± 4.49 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

看上去at的速度比较快。

Where, Masks and Queries

这些都是pandas内置的东西,我个人从来没有用过,主要是因为它们相当多余,而且不经常发生。

他们的速度要快一点。但是感觉可能不值得这样做。所以,如果你想学,就去学吧(文档在here)。如果不是,可能就无关紧要了。

下面让我向您展示如何复制mask功能。

df = pd.DataFrame(np.random.randn(25).reshape((5, 5)))
df.head()
image.png
df.where(df > 0)
image.png
df[df < 0] = np.NaN
df
image.png

小结

这就是我所知道的关于索引的全部内容,并探索所有您需要知道的内容。
如果您有任何问题或意见,请在我的留言!
附:在这方面没有什么特别好的教程,如果你知道有更多更好的,请在留言给我一个教程的链接,感谢!

同步更新于我的个人微信公众号:

快来关注我呀

你可能感兴趣的:(2020-04-19 pandas索引与数据筛选)