【问题标题】:Plotting histograms from grouped data in a pandas DataFrame从 pandas DataFrame 中的分组数据绘制直方图
【发布时间】:2013-11-04 05:29:16
【问题描述】:

我需要一些指导来确定如何根据 pandas 数据框中的分组数据绘制直方图块。这是一个例子来说明我的问题:

from pandas import DataFrame
import numpy as np
x = ['A']*300 + ['B']*400 + ['C']*300
y = np.random.randn(1000)
df = DataFrame({'Letter':x, 'N':y})
grouped = df.groupby('Letter')

在我的无知中,我尝试了这个代码命令:

df.groupby('Letter').hist()

失败并显示错误消息“TypeError: cannot concatenate 'str' and 'float' objects”

非常感谢任何帮助。

【问题讨论】:

    标签: python pandas histogram


    【解决方案1】:

    我正在努力,刚刚找到了一种更简单的方法,使用 hist 方法中的 by 关键字:

    df['N'].hist(by=df['Letter'])
    

    这是快速扫描分组数据的一个非常方便的小快捷方式!

    对于未来的访问者,此次通话的结果如下图:

    【讨论】:

    • 有没有办法在同一个情节中获得这些?
    • 有没有办法为每个子图指定不同的颜色?我尝试传递一组颜色(长度与组数相同),但这似乎不起作用。
    • 有没有办法在y轴上添加标签?
    • 对于更大的情节; df['N'].hist(by=df['Letter']), figsize = (16,18))
    【解决方案2】:

    你的函数失败了,因为你最终得到的 groupby 数据帧有一个分层索引和两列(字母和 N),所以当你做 .hist() 时,它试图制作两列的直方图,因此出现 str 错误。

    这是 pandas 绘图函数的默认行为(每列一个图),因此如果您重塑数据框,使每个字母都是一列,您将得到您想要的。

    df.reset_index().pivot('index','Letter','N').hist()
    

    reset_index() 只是将当前索引推入名为index 的列中。然后pivot 将获取您的数据框,为每个Letter 收集所有值N 并将它们设为一列。生成的数据框为 400 行(用 NaN 填充缺失值)和三列 (A, B, C)。然后hist() 会为每列生成一个直方图,您可以根据需要设置图表的格式。

    【讨论】:

    • 当我遵循这一点时,我不会通过它们的数组来获得我的地块。这对我的方法有一些错误吗?我在 0x246c5fe10 项处得到一组 matplotlib.axes.AxesSubplot 对象。有没有办法让这些显示,比如每行 3 或 4 个?
    • 如果您使用的是 ipython 笔记本,则运行 %pylab 或 %matplotlib 魔术函数以自动显示绘图
    【解决方案3】:

    一种解决方案是直接在每个分组数据帧上使用 matplotlib 直方图。您可以遍历循环中获得的组。每个组都是一个数据框。您可以为每一个创建一个直方图。

    from pandas import DataFrame
    import numpy as np
    x = ['A']*300 + ['B']*400 + ['C']*300
    y = np.random.randn(1000)
    df = DataFrame({'Letter':x, 'N':y})
    grouped = df.groupby('Letter')
    
    for group in grouped:
      figure()
      matplotlib.pyplot.hist(group[1].N)
      show()
    

    【讨论】:

    • 谢谢保罗。我对 'group[1].N' 中的 '[1]' 有点迷惑。当我在 for 循环中添加“打印组”语句时,每个“组”似乎都是一个只有两列(字母和 N)的 DF。在这种情况下,'group.N' 是否足够?
    • 啊,实际上保护了该评论,只是想通了。每个“组”实际上是组名和组 DF 的两个元素元组。哇!
    • 我建议在for循环中拆分元组:for index, group in grouped,然后可以省略[1]
    【解决方案4】:

    使用最新版本的 Pandas,您可以做到 df.N.hist(by=df.Letter)

    就像上面的解决方案一样,每个子图的轴都是不同的。我还没有解决那个问题。

    【讨论】:

    • 您可以使用 sharexsharey 关键字来获取绘图的公共轴,即:df.N.hist(by=df.Letter, sharey=True, sharex=True)
    【解决方案5】:

    我写这个答案是因为我正在寻找一种方法来绘制不同组的直方图。接下来的内容不是很聪明,但对我来说效果很好。我使用 Numpy 计算直方图和 Bokeh 进行绘图。我认为这是不言自明的,但请随时要求澄清,我很乐意添加细节(并写得更好)。

    figures = {
        'Transit': figure(title='Transit', x_axis_label='speed [km/h]', y_axis_label='frequency'),
        'Driving': figure(title='Driving', x_axis_label='speed [km/h]', y_axis_label='frequency')
    }
    
    cols = {'Vienna': 'red', 'Turin': 'blue', 'Rome': 'Orange'}
    for gr in df_trips.groupby(['locality', 'means']):
        locality = gr[0][0]
        means = gr[0][1]
        fig = figures[means]
        h, b = np.histogram(pd.DataFrame(gr[1]).speed.values)
        fig.vbar(x=b[1:], top=h, width=(b[1]-b[0]), legend_label=locality, fill_color=cols[locality], alpha=0.5)
    
    show(gridplot([
        [figures['Transit']],
        [figures['Driving']],
    ]))
    

    【讨论】:

      【解决方案6】:

      我发现这更加简单快捷。

      data_df.groupby('Letter').count()['N'].hist(bins=100)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-05
        • 2018-02-06
        • 1970-01-01
        • 1970-01-01
        • 2019-02-12
        • 2015-10-14
        • 2018-02-04
        • 2023-01-31
        相关资源
        最近更新 更多