熊猫提高效率

时间:2018-07-27 20:11:09

标签: python performance pandas

我有一个大约有300万行的熊猫数据框。 我想根据另一个变量部分地将最后一列汇总到单独的位置。

我的解决方案是根据该变量将数据帧行分成新数据帧列表,聚合数据帧,然后将它们再次合并为单个数据帧。问题是几万行的行之后,出现内存错误。我可以使用哪些方法来提高函数效率以防止这些内存错误?

下面是我的代码示例

test = pd.DataFrame({"unneeded_var": [6,6,6,4,2,6,9,2,3,3,1,4,1,5,9],
                     "year": [0,0,0,0,1,1,1,2,2,2,2,3,3,3,3], 
                     "month" : [0,0,0,0,1,1,1,2,2,2,3,3,3,4,4],
                     "day" : [0,0,0,1,1,1,2,2,2,2,3,3,4,4,5], 
                     "day_count" : [7,4,3,2,1,5,4,2,3,2,5,3,2,1,3]})
test = test[["year", "month", "day", "day_count"]]

def agg_multiple(df, labels, aggvar, repl=None):
    if(repl is None): repl = aggvar
    conds = df.duplicated(labels).tolist() #returns boolean list of false for a unique (year,month) then true until next unique pair
    groups = []
    start = 0
    for i in range(len(conds)): #When false, split previous to new df, aggregate count 
        bul = conds[i]
        if(i == len(conds) - 1): i +=1 #no false marking end of last group, special case
        if not bul and i > 0 or bul and i == len(conds): 
            sample = df.iloc[start:i , :]
            start = i
            sample = sample.groupby(labels, as_index=False).agg({aggvar:sum}).rename(columns={aggvar : repl})
            groups.append(sample)
    df = pd.concat(groups).reset_index(drop=True) #combine aggregated dfs into new df
    return df



test = agg_multiple(test, ["year", "month"], "day_count", repl="month_count")

我想我可以将函数应用于数据帧的小样本,以防止发生内存错误,然后合并这些错误,但是我宁愿缩短函数的计算时间。

2 个答案:

答案 0 :(得分:3)

此功能的作用相同,并且快10倍。

test.groupby(["year", "month"], as_index=False).agg({"day_count":sum}).rename(columns={"day_count":"month_count"})

答案 1 :(得分:2)

几乎总是有{em> 个pandas方法,这些方法针对在数据帧中的迭代性能大大优于迭代的任务进行了优化。如果我理解正确,就您而言,以下内容将返回与您的函数完全相同的输出:

test2 = (test.groupby(['year', 'month'])
         .day_count.sum()
         .to_frame('month_count')
         .reset_index())

>>> test2
   year  month  month_count
0     0      0           16
1     1      1           10
2     2      2            7
3     2      3            5
4     3      3            5
5     3      4            4

要检查是否相同:

# Your original function:
test = agg_multiple(test, ["year", "month"], "day_count", repl="month_count")

>>> test == test2
   year  month  month_count
0  True   True         True
1  True   True         True
2  True   True         True
3  True   True         True
4  True   True         True
5  True   True         True