Pandas 是我最喜爱的库之一。通过带有标签的列和索引,Pandas 使我们可以以一种所有人都能理解的方式来处理数据。它可以让我们毫不费力地从诸如 csv 类型的文件中导入数据。我们可以用它快速地对数据进行复杂的转换和过滤等操作。Pandas 真是超级棒。

我觉得它和 NumpyMatplotlib 一起构成了一个 Python 数据探索和分析的强大基础。Scipy (将会在下一篇推文里介绍)当然也是一大主力并且是一个绝对赞的库,但是我觉得前三者才是 Python 科学计算真正的顶梁柱。

那么,赶紧看看 python 科学计算系列的第三篇推文,一窥 Pandas 的芳容吧。如果你还没看其它几篇文章的话,别忘了去看看。

导入 Pandas

第一件事当然是请出我们的明星 —— Pandas。

Python
<span class="kn">import</span> <span class="nn"><span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/pandas" title="View all posts in pandas" target="_blank">pandas</a></span></span> <span class="kn">as</span> <span class="nn">pd</span> <span class="c"># This is the standard</span>
1
<span class="kn">import</span><span class="nn">pandas</span><span class="kn">as</span><span class="nn">pd</span><span class="c"># This is the standard</span>

这是导入 pandas 的标准方法。我们不想一直写 pandas 的全名,但是保证代码的简洁和避免命名冲突都很重要,所以折中使用 pd 。如果你去看别人使用 pandas 的代码,就会看到这种导入方式。

Pandas 中的数据类型

Pandas 基于两种数据类型,series 和 dataframe。

series 是一种一维的数据类型,其中的每个元素都有各自的标签。如果你之前看过这个系列关于 Numpy 的推文,你可以把它当作一个由带标签的元素组成的 numpy 数组。标签可以是数字或者字符。

dataframe 是一个二维的、表格型的数据结构。Pandas 的 dataframe 可以储存许多不同类型的数据,并且每个轴都有标签。你可以把它当作一个 series 的字典。

将数据导入 Pandas

在对数据进行修改、探索和分析之前,我们得先导入数据。多亏了 Pandas ,这比在 Numpy 中还要容易。

这里我鼓励你去找到自己感兴趣的数据并用来练习。你的(或者别的)国家的网站就是不错的数据源。如果要举例的话,首推英国政府数据和美国政府数据。Kaggle也是个很好的数据源。

我将使用英国降雨数据,这个数据集可以很容易地从英国政府网站上下载到。此外,我还下载了一些日本降雨量的数据。

英国降雨数据:下载地址 日本的数据实在是没找到,抱歉。

Python
<span class="c"># Reading a csv into Pandas.</span> <span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">'uk_rain_2014.csv'</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
1
2

<span class="c"># Reading a csv into Pandas.</span>
<span class="n">df</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">'uk_rain_2014.csv'</span><span class="p">,</span><span class="n">header</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>

译者注:如果你的数据集中有中文的话,最好在里面加上 encoding = 'gbk' ,以避免乱码问题。后面的导出数据的时候也一样。

这里我们从 csv 文件里导入了数据,并储存在 dataframe 中。这一步非常简单,你只需要调用 read_csv 然后将文件的路径传进去就行了。header 关键字告诉 Pandas 哪些是数据的列名。如果没有列名的话就将它设定为 None 。Pandas 非常聪明,所以这个经常可以省略。

准备好要进行探索和分析的数据

现在数据已经导入到 Pandas 了,我们也许想看一眼数据来得到一些基本信息,以便在真正开始探索之前找到一些方向。

查看前 x 行的数据:

Python
<span class="c"># Getting first x rows.</span> <span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
1
2

<span class="c"># Getting first x rows.</span>
<span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

我们只需要调用 head() 函数并且将想要查看的行数传入。

得到的结果如下:

你可能还想看看最后几行:

Python
<span class="c"># Getting last x rows.</span> <span class="n">df</span><span class="o">.</span><span class="n">tail</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
1
2

<span class="c"># Getting last x rows.</span>
<span class="n">df</span><span class="o">.</span><span class="n">tail</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

跟 head 一样,我们只需要调用 tail 并且传入想要查看的行数即可。注意,它并不是从最后一行倒着显示的,而是按照数据原来的顺序显示。

得到的结果如下:

你通常使用列的名字来在 Pandas 中查找列。这一点很好而且易于使用,但是有时列名太长,比如调查问卷的一整个问题。不过你把列名缩短之后一切就好说了。

Python
<span class="c"># Changing column labels.</span> <span class="n">df</span><span class="o">.</span><span class="n">columns</span> <span class="o">=</span> <span class="p">[</span><span class="s">'water_year'</span><span class="p">,</span><span class="s">'rain_octsep'</span><span class="p">,</span> <span class="s">'outflow_octsep'</span><span class="p">,</span> <span class="s">'rain_decfeb'</span><span class="p">,</span> <span class="s">'outflow_decfeb'</span><span class="p">,</span> <span class="s">'rain_junaug'</span><span class="p">,</span> <span class="s">'outflow_junaug'</span><span class="p">]</span> <span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
1
2
3
4
5

<span class="c"># Changing column labels.</span>
<span class="n">df</span><span class="o">.</span><span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="s">'water_year'</span><span class="p">,</span><span class="s">'rain_octsep'</span><span class="p">,</span><span class="s">'outflow_octsep'</span><span class="p">,</span>
<span class="s">'rain_decfeb'</span><span class="p">,</span><span class="s">'outflow_decfeb'</span><span class="p">,</span><span class="s">'rain_junaug'</span><span class="p">,</span><span class="s">'outflow_junaug'</span><span class="p">]</span>
<span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

需要注意的一点是,我故意没有在每列的标签中使用空格和破折号。之后你会看到这样为变量命名可以使我们少打一些字符。

你得到的数据与之前的一样,只是换了列的名字:

你通常会想知道数据的另一个特征——它有多少条记录。在 Pandas 中,一条记录对应着一行,所以我们可以对数据集调用 len 方法,它将返回数据集的总行数:

Python
<span class="c"># Finding out how many rows dataset has.</span> <span class="nb">len</span><span class="p">(</span><span class="n">df</span><span class="p">)</span>
1
2

<span class="c"># Finding out how many rows dataset has.</span>
<span class="nb">len</span><span class="p">(</span><span class="n">df</span><span class="p">)</span>

上面的代码返回一个表示数据行数的整数,在我的数据集中,这个值是 33 。

你可能还想知道数据集的一些基本的统计数据,在 Pandas 中,这个操作简单到哭:

Python
<span class="c"># Finding out basic statistical information on your dataset.</span> <span class="n">pd</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">display</span><span class="o">.</span><span class="n">float_format</span> <span class="o">=</span> <span class="s">'{:,.3f}'</span><span class="o">.</span><span class="n">format</span> <span class="c"># Limit output to 3 decimal places.</span> <span class="n">df</span><span class="o">.</span><span class="n">describe</span><span class="p">()</span>
1
2
3

<span class="c"># Finding out basic statistical information on your dataset.</span>
<span class="n">pd</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">display</span><span class="o">.</span><span class="n">float_format</span><span class="o">=</span><span class="s">'{:,.3f}'</span><span class="o">.</span><span class="n">format</span><span class="c"># Limit output to 3 decimal places.</span>
<span class="n">df</span><span class="o">.</span><span class="n">describe</span><span class="p">()</span>

这将返回一张表,其中有诸如总数、均值、标准差之类的统计数据:

过滤

在探索数据的时候,你可能经常想要抽取数据中特定的样本,比如你有一个关于工作满意度的调查表,你可能就想要提取特定行业或者年龄的人的数据。

在 Pandas 中有多种方法可以实现提取我们想要的信息:

有时你想提取一整列,使用列的标签可以非常简单地做到:

Python
<span class="c"># Getting a column by label</span> <span class="n">df</span><span class="p">[</span><span class="s">'rain_octsep'</span><span class="p">]</span>
1
2

<span class="c"># Getting a column by label</span>
<span class="n">df</span><span class="p">[</span><span class="s">'rain_octsep'</span><span class="p">]</span>

注意,当我们提取列的时候,会得到一个 series ,而不是 dataframe 。记得我们前面提到过,你可以把 dataframe 看作是一个 series 的字典,所以在抽取列的时候,我们就会得到一个 series。

还记得我在命名列标签的时候特意指出的吗?不用空格、破折号之类的符号,这样我们就可以像访问对象属性一样访问数据集的列——只用一个点号。

Python
<span class="c"># Getting a column by label using .</span> <span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span>
1
2

<span class="c"># Getting a column by label using .</span>
<span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span>

这句代码返回的结果与前一个例子完全一样——是我们选择的那列数据。

如果你读过这个系列关于 Numpy 的推文,你可能还记得一个叫做 布尔过滤(boolean masking)的技术,通过在一个数组上运行条件来得到一个布林数组。在 Pandas 里也可以做到。

Python
<span class="c"># Creating a series of booleans based on a conditional</span> <span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span> <span class="o"><</span> <span class="mi">1000</span> <span class="c"># Or df['rain_octsep] < 1000</span>
1
2

<span class="c"># Creating a series of booleans based on a conditional</span>
<span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span><span class="o"><</span><span class="mi">1000</span><span class="c"># Or df['rain_octsep] < 1000</span>

上面的代码将会返回一个由布尔值构成的 dataframe。True 表示在十月-九月降雨量小于 1000 mm,False 表示大于等于 1000 mm。

我们可以用这些条件表达式来过滤现有的 dataframe。

Python
<span class="c"># Using a series of booleans to filter</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span> <span class="o"><</span> <span class="mi">1000</span><span class="p">]</span>
1
2

<span class="c"># Using a series of booleans to filter</span>
<span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span><span class="o"><</span><span class="mi">1000</span><span class="p">]</span>

这条代码只返回十月-九月降雨量小于 1000 mm 的记录:

也可以通过复合条件表达式来进行过滤:

Python
<span class="c"># Filtering by multiple conditionals</span> <span class="n">df</span><span class="p">[(</span><span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span> <span class="o"><</span> <span class="mi">1000</span><span class="p">)</span> <span class="o">&</span> <span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">outflow_octsep</span> <span class="o"><</span> <span class="mi">4000</span><span class="p">)]</span> <span class="c"># Can't use the keyword 'and'</span>
1
2

<span class="c"># Filtering by multiple conditionals</span>
<span class="n">df</span><span class="p">[(</span><span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span><span class="o"><</span><span class="mi">1000</span><span class="p">)</span><span class="o">&</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">outflow_octsep</span><span class="o"><</span><span class="mi">4000</span><span class="p">)]</span><span class="c"># Can't use the keyword 'and'</span>

这条代码只会返回 rain_octsep 中小于 1000 的和 outflow_octsep 中小于 4000 的记录:

注意重要的一点:这里不能用 and 关键字,因为会引发操作顺序的问题。必须用 & 和圆括号。

如果你的数据中字符串,好消息,你也可以使用字符串方法来进行过滤:

Python
<span class="c"># Filtering by string methods</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="o">.</span><span class="n">water_year</span><span class="o">.</span><span class="n">str</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'199'</span><span class="p">)]</span>
1
2

<span class="c"># Filtering by string methods</span>
<span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="o">.</span><span class="n">water_year</span><span class="o">.</span><span class="n">str</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'199'</span><span class="p">)]</span>

注意,你必须用 .str.[string method] ,而不能直接在字符串上调用字符方法。上面的代码返回所有 90 年代的记录:

索引

之前的部分展示了如何通过列操作来得到数据,但是 Pandas 的行也有标签。行标签可以是基于数字的或者是标签,而且获取行数据的方法也根据标签的类型各有不同。

如果你的行标签是数字型的,你可以通过 iloc 来引用:

Python
<span class="c"># Getting a row via a numerical index</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="mi">30</span><span class="p">]</span>
1
2

<span class="c"># Getting a row via a numerical index</span>
<span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="mi">30</span><span class="p">]</span>

iloc 只对数字型的标签有用。它会返回给定行的 series,行中的每一列都是返回 series 的一个元素。

也许你的数据集中有年份或者年龄的列,你可能想通过这些年份或者年龄来引用行,这个时候我们就可以设置一个(或者多个)新的索引:

Python
<span class="c"># Setting a new index from an existing column</span> <span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">set_index</span><span class="p">([</span><span class="s">'water_year'</span><span class="p">])</span> <span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
1
2
3

<span class="c"># Setting a new index from an existing column</span>
<span class="n">df</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">set_index</span><span class="p">([</span><span class="s">'water_year'</span><span class="p">])</span>
<span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

上面的代码将 water_year 列设置为索引。注意,列的名字实际上是一个列表,虽然上面的例子中只有一个元素。如果你想设置多个索引,只需要在列表中加入列的名字即可。

上例中我们设置的索引列中都是字符型数据,这意味着我们不能继续使用 iloc 来引用,那我们用什么呢?用 loc 。

Python
<span class="c"># Getting a row via a label-based index</span> <span class="n">df</span><span class="o">.</span><span class="n">loc</span><span class="p">[</span><span class="s">'2000/01'</span><span class="p">]</span>
1
2

<span class="c"># Getting a row via a label-based index</span>
<span class="n">df</span><span class="o">.</span><span class="n">loc</span><span class="p">[</span><span class="s">'2000/01'</span><span class="p">]</span>

和 iloc 一样,loc 会返回你引用的列,唯一一点不同就是此时你使用的是基于字符串的引用,而不是基于数字的。

还有一个引用列的常用常用方法—— ix 。如果 loc 是基于标签的,而 iloc 是基于数字的,那 ix是基于什么的?事实上,ix 是基于标签的查询方法,但它同时也支持数字型索引作为备选。

Python
<span class="c"># Getting a row via a label-based or numerical index</span> <span class="n">df</span><span class="o">.</span><span class="n">ix</span><span class="p">[</span><span class="s">'1999/00'</span><span class="p">]</span> <span class="c"># Label based with numerical index fallback *Not recommended</span>
1
2

<span class="c"># Getting a row via a label-based or numerical index</span>
<span class="n">df</span><span class="o">.</span><span class="n">ix</span><span class="p">[</span><span class="s">'1999/00'</span><span class="p">]</span><span class="c"># Label based with numerical index fallback *Not recommended</span>

与 ilocloc 一样,它也会返回你查询的行。

如果 ix 可以同时起到 loc 和 iloc 的作用,那为什么还要用后两个?一大原因就是 ix 具有轻微的不可预测性。还记得我说过它所支持的数字型索引只是备选吗?这一特性可能会导致 ix 产生一些奇怪的结果,比如讲一个数字解释为一个位置。而使用 iloc 和 loc 会很安全、可预测并且让人放心。但是我要指出的是,ix 比 iloc 和 loc 要快一些。

将索引排序通常会很有用,在 Pandas 中,我们可以对 dataframe 调用 sort_index 方法进行排序。

Python
<span class="n">df</span><span class="o">.</span><span class="n">sort_index</span><span class="p">(</span><span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="c">#inplace=True to apple the sorting in place</span>
1
<span class="n">df</span><span class="o">.</span><span class="n">sort_index</span><span class="p">(</span><span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="c">#inplace=True to apple the sorting in place</span>

我的索引本来就是有序的,为了演示,我将参数 ascending 设置为 false,这样我的数据就会呈降序排列。

当你将一列设置为索引的时候,它就不再是数据的一部分了。如果你想将索引恢复为数据,调用 set_index 相反的方法 reset_index 即可:

Python
<span class="c"># Returning an index to data</span> <span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">reset_index</span><span class="p">(</span><span class="s">'water_year'</span><span class="p">)</span> <span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
1
2
3

<span class="c"># Returning an index to data</span>
<span class="n">df</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">reset_index</span><span class="p">(</span><span class="s">'water_year'</span><span class="p">)</span>
<span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

这一语句会将索引恢复成数据形式:

对数据集应用函数

有时你想对数据集中的数据进行改变或者某种操作。比方说,你有一列年份的数据,你需要新的一列来表示这些年份对应的年代。Pandas 中有两个非常有用的函数,apply 和 applymap

Python
<span class="c"># Applying a function to a column</span> <span class="k">def</span> <span class="nf">base_year</span><span class="p">(</span><span class="n">year</span><span class="p">):</span> <span class="n">base_year</span> <span class="o">=</span> <span class="n">year</span><span class="p">[:</span><span class="mi">4</span><span class="p">]</span> <span class="n">base_year</span><span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="n">base_year</span><span class="p">)</span><span class="o">.</span><span class="n">year</span> <span class="k">return</span> <span class="n">base_year</span> <span class="n">df</span><span class="p">[</span><span class="s">'year'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">water_year</span><span class="o">.</span><span class="n">apply</span><span class="p">(</span><span class="n">base_year</span><span class="p">)</span> <span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
1
2
3
4
5
6
7
8

<span class="c"># Applying a function to a column</span>
<span class="k">def</span><span class="nf">base_year</span><span class="p">(</span><span class="n">year</span><span class="p">):</span>
<span class="n">base_year</span><span class="o">=</span><span class="n">year</span><span class="p">[:</span><span class="mi">4</span><span class="p">]</span>
<span class="n">base_year</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="n">base_year</span><span class="p">)</span><span class="o">.</span><span class="n">year</span>
<span class="k">return</span><span class="n">base_year</span>
<span class="n">df</span><span class="p">[</span><span class="s">'year'</span><span class="p">]</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">water_year</span><span class="o">.</span><span class="n">apply</span><span class="p">(</span><span class="n">base_year</span><span class="p">)</span>
<span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

上面的代码创建了一个叫做 year 的列,它只将 water_year 列中的年提取了出来。这就是 apply的用法,即对一列数据应用函数。如果你想对整个数据集应用函数,就要使用 applymap 。

操作数据集的结构

另一常见的做法是重新建立数据结构,使得数据集呈现出一种更方便并且(或者)有用的形式。

掌握这些转换最简单的方法就是观察转换的过程。比起这篇文章的其他部分,接下来的操作需要你跟着练习以便能掌握它们。

首先,是 groupby :

Python
<span class="c">#Manipulating structure (groupby, unstack, pivot)</span> <span class="c"># Grouby</span> <span class="n">df</span><span class="o">.</span><span class="n">groupby</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">year</span> <span class="o">//</span> <span class="mi">10</span> <span class="o">*</span><span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="n">max</span><span class="p">()</span>
1
2
3

<span class="c">#Manipulating structure (groupby, unstack, pivot)</span>
<span class="c"># Grouby</span>
<span class="n">df</span><span class="o">.</span><span class="n">groupby</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">year</span><span class="o">//</span><span class="mi">10</span><span class="o">*</span><span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="n">max</span><span class="p">()</span>

groupby 会按照你选择的列对数据集进行分组。上例是按照年代分组。不过仅仅这样做并没有什么用,我们必须对其调用函数,比如 max 、 min 、mean 等等。例中,我们可以得到 90 年代的均值。

你也可以按照多列进行分组:

Python
<span class="c"># Grouping by multiple columns</span> <span class="n">decade_rain</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">groupby</span><span class="p">([</span><span class="n">df</span><span class="o">.</span><span class="n">year</span> <span class="o">//</span> <span class="mi">10</span> <span class="o">*</span> <span class="mi">10</span><span class="p">,</span> <span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span> <span class="o">//</span> <span class="mi">1000</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">])[[</span><span class="s">'outflow_octsep'</span><span class="p">,</span> <span class="s">'outflow_decfeb'</span><span class="p">,</span> <span class="s">'outflow_junaug'</span><span class="p">]]</span><span class="o">.</span><span class="n">mean</span><span class="p">()</span> <span class="n">decade_rain</span>
1
2
3

<span class="c"># Grouping by multiple columns</span>
<span class="n">decade_rain</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">groupby</span><span class="p">([</span><span class="n">df</span><span class="o">.</span><span class="n">year</span><span class="o">//</span><span class="mi">10</span><span class="o">*</span><span class="mi">10</span><span class="p">,</span><span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span><span class="o">//</span><span class="mi">1000</span><span class="o">*</span><span class="mi">1000</span><span class="p">])[[</span><span class="s">'outflow_octsep'</span><span class="p">,</span><span class="s">'outflow_decfeb'</span><span class="p">,</span><span class="s">'outflow_junaug'</span><span class="p">]]</span><span class="o">.</span><span class="n">mean</span><span class="p">()</span>
<span class="n">decade_rain</span>

接下来是 unstack ,最开始可能有一些困惑,它可以将一列数据设置为列标签。最好还是看看实际的操作:

Python
<span class="c"># Unstacking</span> <span class="n">decade_rain</span><span class="o">.</span><span class="n">unstack</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
1
2

<span class="c"># Unstacking</span>
<span class="n">decade_rain</span><span class="o">.</span><span class="n">unstack</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

这条语句将上例中的 dataframe 转换为下面的形式。它将第 0 列,也就是 year 列设置为列的标签。

让我们再操作一次。这次使用第 1 列,也就是 rain_octsep 列:

Python
<span class="c"># More unstacking</span> <span class="n">decade_rain</span><span class="o">.</span><span class="n">unstack</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
1
2

<span class="c"># More unstacking</span>
<span class="n">decade_rain</span><span class="o">.</span><span class="n">unstack</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>

在进行下次操作之前,我们先创建一个用于演示的 dataframe :

Python
<span class="c"># Create a new dataframe containing entries which </span> <span class="c"># has rain_octsep values of greater than 1250</span> <span class="n">high_rain</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span> <span class="o">></span> <span class="mi">1250</span><span class="p">]</span> <span class="n">high_rain</span>
1
2
3
4

<span class="c"># Create a new dataframe containing entries which </span>
<span class="c"># has rain_octsep values of greater than 1250</span>
<span class="n">high_rain</span><span class="o">=</span><span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="o">.</span><span class="n">rain_octsep</span><span class="o">></span><span class="mi">1250</span><span class="p">]</span>
<span class="n">high_rain</span>

上面的代码将会产生如下的 dataframe ,我们将会在上面演示轴向旋转(pivoting)

轴旋转其实就是我们之前已经看到的那些操作的一个集合。首先,它会设置一个新的索引(set_index()),然后对索引排序(sort_index()),最后调用 unstack 。以上的步骤合在一起就是 pivot 。接下来看看你能不能搞清楚下面的代码在干什么:

Python
<span class="c">#Pivoting</span> <span class="c">#does set_index, sort_index and unstack in a row</span> <span class="n">high_rain</span><span class="o">.</span><span class="n">pivot</span><span class="p">(</span><span class="s">'year'</span><span class="p">,</span> <span class="s">'rain_octsep'</span><span class="p">)[[</span><span class="s">'outflow_octsep'</span><span class="p">,</span> <span class="s">'outflow_decfeb'</span><span class="p">,</span> <span class="s">'outflow_junaug'</span><span class="p">]]</span><span class="o">.</span><span class="n">fillna</span><span class="p">(</span><span class="s">''</span><span class="p">)</span>
1
2
3

<span class="c">#Pivoting</span>
<span class="c">#does set_index, sort_index and unstack in a row</span>
<span class="n">high_rain</span><span class="o">.</span><span class="n">pivot</span><span class="p">(</span><span class="s">'year'</span><span class="p">,</span><span class="s">'rain_octsep'</span><span class="p">)[[</span><span class="s">'outflow_octsep'</span><span class="p">,</span><span class="s">'outflow_decfeb'</span><span class="p">,</span><span class="s">'outflow_junaug'</span><span class="p">]]</span><span class="o">.</span><span class="n">fillna</span><span class="p">(</span><span class="s">''</span><span class="p">)</span>

注意,最后有一个 .fillna('') 。pivot 产生了很多空的记录,也就是值为 NaN 的记录。我个人觉得数据集里面有很多 NaN 会很烦,所以使用了 fillna('') 。你也可以用别的别的东西,比方说 0 。我们也可以使用 dropna(how = 'any') 来删除有 NaN 的行,不过这样就把所有的数据都删掉了,所以不这样做。

上面的 dataframe 展示了所有降雨超过 1250 的 outflow 。诚然,这并不是讲解 pivot 实际应用最好的例子,但希望你能明白它的意思。看看你能在你的数据集上得到什么结果。

合并数据集

有时你有两个相关联的数据集,你想将它们放在一起比较或者合并它们。好的,没问题,在 Pandas 里很简单:

Python
<span class="c"># Merging two datasets together</span> <span class="n">rain_jpn</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">'jpn_rain.csv'</span><span class="p">)</span> <span class="n">rain_jpn</span><span class="o">.</span><span class="n">columns</span> <span class="o">=</span> <span class="p">[</span><span class="s">'year'</span><span class="p">,</span> <span class="s">'jpn_rainfall'</span><span class="p">]</span> <span class="n">uk_jpn_rain</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">rain_jpn</span><span class="p">,</span> <span class="n">on</span><span class="o">=</span><span class="s">'year'</span><span class="p">)</span> <span class="n">uk_jpn_rain</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
1
2
3
4
5
6

<span class="c"># Merging two datasets together</span>
<span class="n">rain_jpn</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">'jpn_rain.csv'</span><span class="p">)</span>
<span class="n">rain_jpn</span><span class="o">.</span><span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="s">'year'</span><span class="p">,</span><span class="s">'jpn_rainfall'</span><span class="p">]</span>
<span class="n">uk_jpn_rain</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">rain_jpn</span><span class="p">,</span><span class="n">on</span><span class="o">=</span><span class="s">'year'</span><span class="p">)</span>
<span class="n">uk_jpn_rain</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

首先你需要通过 on 关键字来指定需要合并的列。通常你可以省略这个参数,Pandas 将会自动选择要合并的列。

如下图所示,两个数据集在年份这一类上合并了。jpn_rain 数据集只有年份和降雨量两列,通过年份列合并之后,jpn_rain 中只有降雨量那一列合并到了 UK_rain 数据集中。

使用 Pandas 快速作图

Matplotlib 很棒,但是想要绘制出还算不错的图表却要写不少代码,而有时你只是想粗略的做个图来探索下数据,搞清楚数据的含义。Pandas 通过 plot 来解决这个问题:

Python
<span class="c"># Using pandas to quickly plot graphs</span> <span class="n">uk_jpn_rain</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="s">'year'</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="p">[</span><span class="s">'rain_octsep'</span><span class="p">,</span> <span class="s">'jpn_rainfall'</span><span class="p">])</span>
1
2

<span class="c"># Using pandas to quickly plot graphs</span>
<span class="n">uk_jpn_rain</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="s">'year'</span><span class="p">,</span><span class="n">y</span><span class="o">=</span><span class="p">[</span><span class="s">'rain_octsep'</span><span class="p">,</span><span class="s">'jpn_rainfall'</span><span class="p">])</span>

这会调用 Matplotlib 快速轻松地绘出了你的数据图。通过这个图你就可以在视觉上分析数据,而且它能在探索数据的时候给你一些方向。比如,看到我的数据图,你会发现在 1995 年的英国好像有一场干旱。

你会发现英国的降雨明显少于日本,但人们却说英国总是下雨。

保存你的数据集

在清洗、重塑、探索完数据之后,你最后的数据集可能会发生很大改变,并且比最开始的时候更有用。你应该保存原始的数据集,但是你同样应该保存处理之后的数据。

Python
<span class="c"># Saving your data to a csv</span> <span class="n">df</span><span class="o">.</span><span class="n">to_csv</span><span class="p">(</span><span class="s">'uk_rain.csv'</span><span class="p">)</span>
1
2

<span class="c"># Saving your data to a csv</span>
<span class="n">df</span><span class="o">.</span><span class="n">to_csv</span><span class="p">(</span><span class="s">'uk_rain.csv'</span><span class="p">)</span>

上面的代码将会保存你的数据到 csv 文件以便下次使用。

我们对 Pandas 的介绍就到此为止了。就像我之前所说的, Pandas 非常强大,我们只是领略到了一点皮毛而已,不过你现在知道的应该足够你开始清洗和探索数据了。

像以前一样,我建议你用自己感兴趣的数据集做一下练习,坐下来,一杯啤酒配数据。这确实是你唯一熟悉 Pandas 以及这个系列其他库的方式。而且你也许会发现一些有趣的东西。

  • zeropython 微信公众号 5868037 QQ号 5868037@qq.com QQ邮箱

十分钟快速入门 Pandas相关推荐

  1. python新手教程 从零开始-Python零基础从零开始学习Python十分钟快速入门

    原标题:Python零基础从零开始学习Python十分钟快速入门 学习Python的,都知道Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言.Python是一种动态解释型的 ...

  2. Python语言十分钟快速入门

    假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(CheatSheet ...

  3. 嘉立创专业板stm32拓展板十分钟快速入门

    本文是为不想深入学PCB但是迫不得已需要用PCB的人或者想要做一个32的拓展版的童鞋们的快速入门并做出板子的博客,因此,本文内容不会深入讨论元件,只会教授基础流程,并且没有画芯片. 本文内容:1.如何 ...

  4. python语言入门u-Python语言十分钟快速入门

    [简介] Python(蟒蛇)是一种动态解释型的编程语言.Python可以在Windows.UNIX.MAC等多种操作系统上使用,也可以在Java..NET开发平台上使用. python logo [ ...

  5. python语言入门教程-Python语言十分钟快速入门

    [简介] Python(蟒蛇)是一种动态解释型的编程语言.Python可以在Windows.UNIX.MAC等多种操作系统上使用,也可以在Java..NET开发平台上使用. python logo [ ...

  6. python语言入门-Python语言十分钟快速入门

    [简介] Python(蟒蛇)是一种动态解释型的编程语言.Python可以在Windows.UNIX.MAC等多种操作系统上使用,也可以在Java..NET开发平台上使用. python logo [ ...

  7. 带你十分钟快速入门画图绘图作图神器 Matplotlib_各种画图小结

    20220612 excel也可以画图 20220525 U-net架构(例如最低分辨率为32x32像素).每个蓝框对应一个多通道特征图.通道的数量在方框的顶部表示.x-y尺寸在盒子的左下边缘.白盒代 ...

  8. python开发pc软件_程序员带你十天快速入门Python,玩转电脑软件开发(二)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  9. python做电脑软件-程序员带你十天快速入门Python,玩转电脑软件开发(二)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  10. python入门教程软件-程序员带你十天快速入门Python,玩转电脑软件开发(四)

    本系列文章立志于从一个已经习得一门编程语言的基础之上,全面介绍Python的相关开发过程和相关经验总结.本篇文章主要是基于上一篇的程序员带你十天快速入门Python,玩转电脑软件开发(三)的基础之上, ...

最新文章

  1. c语言simpson积分计算方法,数值分析复化Simpson积分公式和复化梯形积分公式计算积分的通用程序...
  2. php json csv,比JSON更简单,随便记数据的CSV介绍,以及PHP解析方法-csv文件怎么打开...
  3. python题目推荐_python题目
  4. GIS实战应用案例100篇(二)-元胞自动机模拟城市扩张过程
  5. 第一次收到这么用心的感谢信
  6. LeetCode 841. 钥匙和房间(DFS/BFS)
  7. C语言和C++的区别整理详解!
  8. 你不知道的javascript读书笔记3
  9. 零基础带你学习MySQL—Delete语句以及注意事项(九)
  10. html设置nav标签高度,html – Bootstrap带导航栏的100%高度
  11. 分享微信朋友或朋友圈
  12. 快解析:管家婆C9异地访问解决方案
  13. 2016最新淘宝客申请高佣金以及分析抓包详情
  14. Vue 按enter键实现登陆 过程
  15. 零知识证明 - bellman源码分析
  16. 工作中有可能用到的运维小知识《现查现用》
  17. Dart_Flutter【插件介绍+平台发布+视频】【180个网址导航】
  18. 改善睡眠失眠10大方法,让你失眠一招入睡
  19. JGG | 中国中医科学院仝小林团队/李敏团队和长春中医药大学王泽玉团队合作综述调控肠干细胞代谢活动的关键因素...
  20. java服务器保存特殊字符和表情入库报错

热门文章

  1. 环保数采仪环境污染在线监控设备 上传监控平台
  2. 跨省游恢复,首旅如家发布暑期16座旅游目的地城市攻略
  3. bcm43142 linux 驱动下载,CentosRedhat下bcm43142博通无线网卡linux驱动之二
  4. python seek_关于python:seek()函数?
  5. MOSS入门介绍 和 概念介绍
  6. PAT乙级1068 万绿丛中一点红(测试点3、测试点5)
  7. Swing-右键菜单
  8. linux+暂停运行,如何暂停和继续运行Linux程序
  9. 分子模拟软件amber_分子模拟周刊: 第 23 期
  10. 2022茶艺师(初级)考试试题模拟考试平台操作