从pandas dataframe

时间:2015-07-16 16:57:45

标签: python performance numpy pandas histogram

我想从pandas dataframe中的分组数据创建一堆直方图。这是a link类似的问题。要生成一些与我正在使用的玩具数据非常相似的玩具数据,您可以使用以下代码:

    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})

我想将这些直方图(读取分箱数据)放在一个新的数据帧中并保存以供以后处理。这是真正的踢球者,我的文件是6 GB,有400k +组,只有2列。

我已经考虑过使用简单的for循环来完成工作:

    data=[]
    for group in df['Letter'].unique():
        data.append(np.histogram(df[df['Letter']==group]['N'],range=(-2000,2000),bins=50,density=True)[0])
    df2=DataFrame(data)

请注意,bin,range和density关键字对于我的目的来说都是必需的,因此直方图在我的新数据帧df2中的行中是一致的和标准化的(参数值来自我的真实数据集,因此它对玩具数据集的过度杀伤力)。并且for循环工作得很好,玩具数据集会按预期生成3行50列的pandas数据帧。在我的真实数据集中,我估计完成代码的时间大约为9天。是否有更好/更快的方式来做我正在寻找的事情?

P.S。我已经考虑过多处理,但是我认为创建进程和切片数据的开销要比连续运行这样做要慢(我可能错了,并且不介意在这个问题上纠正)。

1 个答案:

答案 0 :(得分:1)

对于您在此描述的问题类型,我个人通常会执行以下操作,基本上将整个事务委托给多线程Cython / C ++。这是一项工作,但并非不可能,而且我不确定目前是否真的有可行的选择。

以下是构建基块:

  • 首先,您的df.x.valuesdf.y.values只是numpy数组。 This link展示了如何从这样的数组中获取C指针。

  • 现在您已经有了指针,您可以使用Cython的prange编写一个真正的多线程程序,并从此处开始介绍任何Python(您现在处于C ++领域)。所以说你有 k 线程扫描你的6GB阵列,线程 i 处理其键具有 i modulo k的散列的组

  • 对于C程序(这是您现在的代码),GNU Scientific Library有一个nice histogram module

  • prange完成后,您需要将C ++结构转换回numpy数组,然后从那里转换回DataFrame。在Cython中包装整个内容,并像普通的Python函数一样使用它。