将系列分组 pandas

Grouping a series in pandas

我是 pandas 的新手。我对此了解不多,所以请放轻松。 我试图在折线图中绘制 2009 年至 2013 年 A 区和 B 区的面积与火灾频率。我想出了如何导入 .csv 文件,但我在对系列进行分组和创建图形时遇到问题。 我的 csv 文件如下所示:

Date, Area, NaturalDisaster
12/10/2009, A, Fire
12/13/2009, B, Flood
01/12/2010, B, Fire
05/01/2011, A, Fire
30/11/2012, B, Flood
14/03/2013, B, Fire

所以你能帮我开始吗?我将不胜感激任何形式的帮助。 谢谢。

您可以使用 pandas.DataFrame.groupby 对 pandas 中的数据进行分组。

groupby 和类似功能背后的主要思想是 "Split - Apply - Combine",一般来说,您:

  • 将您的数据集分成几组,
  • 对每个单独的组应用一些聚合函数,
  • Re-combine 它们在一个新的数据框中。

要获得 A 区和 B 区内发生火灾的频率,您必须首先 select 只有发生火灾而非洪水的行,您可以使用 boolean indexing 执行此操作:

df[df['NaturalDisaster']=='Fire']

然后您需要根据区域(A 或 B)分组(或拆分)。您只需使用 groupby('Area') 即可完成此操作。将此添加到上一行代码,这将变为:

df[df['NaturalDisaster']=='Fire'].groupby('Area')

最后在pandas你需要apply some aggregate function到你的小组(申请阶段),我们将使用count()来计算结果的数量。然后这一行变成:

df[df['NaturalDisaster']=='Fire'].groupby('Area').count()

但是有一个问题。此结果有两列,其中的数字完全相同。那是因为我们计算了 Date 列和 NaturalDisaster 列。这种重复的信息处理起来很烦人,所以让我们在计数时只取一列。最后一行变成

areas = df[df['NaturalDisaster']=='Fire'].groupby('Area')['NaturalDisaster'].count()

我们现在有了 A 区和 B 区发生的火灾事件的计数,但理想情况下我们需要频率。我们可以通过除以由 sum(areas):

给出的火灾事件总数得到
areas /= sum(areas)

我们现在有一个包含 A 区和 B 区火灾事件频率的数据框。我们可以 plot this as a bar chart 简单地使用

areas.plot(kind='bar')

把所有的代码合并成一堆,就变成了:

from io import StringIO

import pandas as pd
import matplotlib.pyplot as plt


s = '''Date, Area, NaturalDisaster
12/10/2009, A, Fire
12/13/2009, B, Flood
01/12/2010, B, Fire
05/01/2011, A, Fire
30/11/2012, B, Flood
14/03/2013, B, Fire'''

df = pd.read_csv(StringIO(s), sep=',\s+', engine='python')

# Ignore everything above this part, it's simply creating your dataframe.

areas = df[df['NaturalDisaster']=='Fire'].groupby('Area')['NaturalDisaster'].count() 
areas /= sum(areas)

areas.plot(kind='bar')

plt.show()

最后,我使用 groupby 回答了这个问题,因为您专门询问了它,但您也可以使用 pandas.pivot_table 来执行相同的操作(以及类似的强大功能)。使用 pivot_table 创建 areas 数据框类似于

areas = pd.pivot_table(df[df['NaturalDisaster']=='Fire'],
                       values='NaturalDisaster', 
                       index='Area', 
                       aggfunc='count')

然后您将继续使用上面给出的相同代码。