为多索引数据框应用函数

时间:2018-04-10 03:16:35

标签: python

我有一个多索引数据框,按日期和库存编制索引。这是一个例子:

                     Column1
Date        Ticker
2008-08-01  AAPL     value1
            MSFT     value2
            IBM      value3
            etc.
2008-08-02  AAPL     value4
            MSFT     value5
            IBM      value6
            etc.

我要做的是为每个日期将一个函数应用于此列,然后替换该列。例如,对于每个日期,从2008-08-01开始,我想要得到Column1的平均值,并取每个股票代码的值与此平均值之间的差值。然后Column1将被这些值替换。我最终得到了:

                     Column1
Date        Ticker
2008-08-01  AAPL     avg(Column1, 8/1/08) - value1
            MSFT     avg(Column1, 8/1/08) - value2
            IBM      avg(Column1, 8/1/08) - value3
            etc.
2008-08-02  AAPL     avg(Column1, 8/2/08) - value4
            MSFT     avg(Column1, 8/2/08) - value5
            IBM      avg(Column1, 8/2/08) - value6
            etc.

我可以通过以下方式实现这一目标:

df = df.copy()
col1_adjusted = [func(df.loc[df.index.get_level_values('Date') == date]['Column1']) for date in dates]
col1_adjusted = [item for sublist in col1_adjusted for item in sublist]
df.Column1= col1_adjusted 

但这需要很长时间,因为我有很多约会。有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

Debasish对于split-apply-combine方法是正确的。举个简单的例子:

# Use groupby to find the average by date; sub in w/e func for mean    
df['Column2'] = df.groupby(level='Date').transform('mean')

# Replace Column1 with the desired value
df['Column1'] = df['Column2'] - df['Column1']

上面的例子是为了清晰起见,但这里是更好的,单线:

df['Column1'] = df.groupby(level='Date')['Column1'].transform('mean').sub(df['Column1'])