我有一个大熊猫数据框(约 1300 万行),其中包含各种项目的数据,每个项目都有不同月份的观察结果。这些项目根据相应行的数量(即具有观察数据的月份)而变化,并且月份可能是连续的,也可能不是连续的。高度缩写的简化示例:
x y
item_id date
4 2006-01-01 5.69368 0.789752
2006-02-01 5.67199 0.786743
2006-03-01 5.66469 0.783626
2006-04-01 5.69427 0.782596
2006-05-01 5.70198 0.781670
5 2006-05-01 3.16992 1.000000
2006-07-01 3.25000 0.978347
我需要为数据完成以下工作:对于每个项目,从该项目的第一个观察到的行向前填充观察到指定的最大日期。因此,给定上面的示例,所需的输出如下:
x y
item_id
4 2006-01-01 5.69368 0.789752
2006-02-01 5.67199 0.786743
2006-03-01 5.66469 0.783626
2006-04-01 5.69427 0.782596
2006-05-01 5.70198 0.781670
2006-06-01 5.70198 0.781670
2006-07-01 5.70198 0.781670
2006-08-01 5.70198 0.781670
2006-09-01 5.70198 0.781670
2006-10-01 5.70198 0.781670
2006-11-01 5.70198 0.781670
2006-12-01 5.70198 0.781670
5 2006-05-01 3.16992 1.000000
2006-06-01 3.16992 1.000000
2006-07-01 3.25000 0.978347
2006-08-01 3.25000 0.978347
2006-09-01 3.25000 0.978347
2006-10-01 3.25000 0.978347
2006-11-01 3.25000 0.978347
2006-12-01 3.25000 0.978347
为了便于进一步分析,我需要将日期索引转换为简单的数字索引(我们将其称为“seq”),这样最终的结果是:
x y
item_id seq
4 0 5.69368 0.789752
1 5.67199 0.786743
2 5.66469 0.783626
3 5.69427 0.782596
4 5.70198 0.781670
5 5.70198 0.781670
6 5.70198 0.781670
7 5.70198 0.781670
8 5.70198 0.781670
9 5.70198 0.781670
10 5.70198 0.781670
11 5.70198 0.781670
5 0 3.16992 1.000000
1 3.16992 1.000000
2 3.25000 0.978347
3 3.25000 0.978347
4 3.25000 0.978347
5 3.25000 0.978347
6 3.25000 0.978347
7 3.25000 0.978347
(这样做的目的是让我对项目的第一个、第二个、...、第 n 个观察值进行平均)。无论如何,如果我只对数据的一个子集进行操作,我有一个可以正常工作的解决方案:
df = pd.read_table(filename,sep='\s*',header=None,names=['item_id','date','x','y'],index_col=['item_id','date'],parse_dates='date')
maxDate = '2006-12-01'
def switchToSeqIndex(df):
minDate = df.index[0][1] # get the first observed date
return df.reset_index(level='item_id',drop=True).reset_index(). \
set_index('date').reindex(pd.date_range(minDate,maxDate,freq='MS'), \
method='ffill').reset_index('date',drop=True)
df_fixed = df.groupby(level='item_id').apply(switchToSeqIndex)
df_fixed.index.names[1]='seq'
原则上这很好,并且会生成正确的输出,但是当我尝试对整个数据集(1300 万行,通过重新索引扩展大量数据)执行操作时,内存使用失控(用20GB 内存)。
那么,我的问题是如何在减少内存开销的同时做到这一点。我认为问题在于尝试使用 groupby/apply 方法执行重新索引,但我不知道替代方法是什么。似乎应该有办法我可以迭代地做类似的事情,这需要更少的内存,但我不知道如何去做。