使用Pandas GroupBy绘制结果

39
我正开始学习 Pandas,并且正在尝试找到实现某些任务的最 Pythonic(或“Panda-thonic”)方法。
假设我们有一个包含列 A、B 和 C 的 DataFrame。
列 A 包含布尔值:每行的 A 值都是 true 或 false。
列 B 具有一些重要值,我们想要绘制这些值。
我们想要发现的是,对于将 A 设置为 false 的行和对于 A 为 true 的行,B 值之间的微妙差别。
换句话说,如何按列 A 的值(true 或 false)进行分组,然后在同一图表上绘制两个组的列 B 值?这两个数据集应该以不同的颜色着色,以便区分数据点。
接下来,让我们为这个程序添加另一个特性:在绘图之前,我们要计算每行的另一个值并将其存储在列 D 中。这个值是在记录前五分钟内存储在列 B 中的所有数据的平均值,但我们只包括存储在 A 中相同布尔值的行。
换句话说,如果我有一个行,其中 A=True 并且 time=t,则我希望为每个时间点 t 计算一个列 D 的值,该值是从时间 t-5 到 t 中存储了相同布尔值 A=True 的所有记录的 B 值的平均值。
在这种情况下,我们如何按 A 的值执行 groupby,然后将此计算应用于每个单独的组,并最终绘制两个组的 D 值?

4
你有一些数据框示例吗?似乎可以将分组对象存储在变量中:grouped = df.groupby('A'),然后用for循环绘制图表:for g, d in grouped: plot(d['B'], color=g)。第二个问题也差不多,可以使用pandas的rolling_mean来创建新列D。 - herrfz
1个回答

43

我认为@herrfz已经提到了所有要点,我只需要详细阐述一下:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

sin = np.sin
cos = np.cos
pi = np.pi
N = 100

x = np.linspace(0, pi, N)
a = sin(x)
b = cos(x)

df = pd.DataFrame({
    'A': [True]*N + [False]*N,
    'B': np.hstack((a,b))
    })

for key, grp in df.groupby(['A']):
    plt.plot(grp['B'], label=key)
    grp['D'] = pd.rolling_mean(grp['B'], window=5)    
    plt.plot(grp['D'], label='rolling ({k})'.format(k=key))
plt.legend(loc='best')    
plt.show()

在此输入图片描述


太好了!您能否谈一下如何实现更多定制的计算方式来处理D列,如果我想要进行一些特殊的计算,而内置的“rolling” Pandas函数无法满足需求呢?谢谢。 (@herrfz) - Maxim Zaslavsky
rolling_mean只是Pandas中众多滚动函数之一。要定义自定义滚动函数,请使用rolling_apply。链接页面上有一个示例。 - unutbu
谢谢。我在尝试将那个例子适应到我想要完成的任务时遇到了困难,所以我在这里又问了一个问题:https://dev59.com/9G_Xa4cB1Zd3GeqP5dFD - Maxim Zaslavsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接