pandas 数据框 - 增加多重索引数据框中特定时间范围子集的值

0 投票
1 回答
886 浏览
提问于 2025-04-17 22:06

以下代码在pandas 12.0版本上运行得很好,但在pandas 13版本上就不行了(处理每条记录的时间大约是1分钟,而之前处理20万条记录只需要一个小时左右)。

我怀疑有更优雅的方法可以达到同样的效果。如果有人能给我指个方向就太好了。

我这样创建数据框:

pubs = ['pub1','pub2','pub3','pub4','pub5']

panel = pd.Panel(np.random.randn(2,2200,5), items=['variableA','variableB'], major_axis=pd.date_range('20110101', periods=2200), minor_axis=pubs)
df_sub = panel.to_frame()
df_sub.ix[:] = 0

我这样增加数值:

startDate = time.ctime(time.mktime(time.strptime(meh,"%d/%m/%Y %H:%M:%S")))
TempRng = pd.date_range(startDate, periods=75)
for eachDay in TempRng:
    df_sub.ix[eachDay,pubID]['variableA'] +=1
    df_sub.ix[eachDay,pubID]['variableB'] += 5

^^这最后一部分一个月前运行得很好,但现在却变得非常慢。在另一台仍然使用旧版本pandas的机器上,处理速度是可以接受的。

那么,正确的增加数值的方法是什么呢?

1 个回答

2

把你现在的做法反过来,先从数量少的酒吧开始处理,这样会快很多。使用Ix/loc来设置大范围的数据时非常迅速,但如果只是对少量数据进行多次修改,这样做就不太划算了。

In [57]: df = df_sub.reset_index()

In [58]: mask = df.minor == 'pub1'

In [59]: df.loc[mask,'variableA'] = 1

In [60]: df.loc[mask,'variableB'] = 5

In [61]: df.loc[mask,'variableA'] = df.loc[mask,'variableA'].cumsum()

In [62]: df.loc[mask,'variableB'] = df.loc[mask,'variableB'].cumsum()

In [64]: df.set_index(['major','minor']).head(20)
Out[64]: 
                  variableA  variableB
major      minor                      
2011-01-01 pub1           1          5
           pub2           0          0
           pub3           0          0
           pub4           0          0
           pub5           0          0
2011-01-02 pub1           2         10
           pub2           0          0
           pub3           0          0
           pub4           0          0
           pub5           0          0
2011-01-03 pub1           3         15
           pub2           0          0
           pub3           0          0
           pub4           0          0
           pub5           0          0
2011-01-04 pub1           4         20
           pub2           0          0
           pub3           0          0
           pub4           0          0
           pub5           0          0

[20 rows x 2 columns]

在0.14版本中,你将能够直接对第二层进行索引和设置。

idx = pd.IndexSlice

df_sub.loc[idx[:,'pub1'],:] = 1

撰写回答