将系列分组 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')
然后您将继续使用上面给出的相同代码。
我是 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')
然后您将继续使用上面给出的相同代码。