如何使用Pandas多索引数据帧中的先前值进行计算?

2024-09-27 04:24:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面的多索引数据帧。在

                         Close     ATR     
Date          Symbol     
1990-01-01    A          24        2       
1990-01-01    B          72        7      
1990-01-01    C          40        3.4 

1990-01-02    A          21        1.5     
1990-01-02    B          65        6        
1990-01-02    C          45        4.2   

1990-01-03    A          19        2.5    
1990-01-03    B          70        6.3       
1990-01-03    C          51        5 

我要计算三列:

  • Shares=前一天的Equity*0.02/ATR,四舍五入到整数

  • Profit=Shares*Close

  • Equity=前一天的Equity+每个SymbolProfit之和

Equity的初始值为10000。在

预期产出为:

^{pr2}$

我想我需要一个for loop或一个function应用于每一行。关于这些,我有两个问题。一个是我不确定如何在MultiIndex数据帧的情况下为这个逻辑创建for loop。第二个原因是我的数据帧非常大(大约1000万行),所以我不确定for loop是否是个好主意。但是如何创建这些列呢?在


Tags: 数据loopforclosedate情况function整数
2条回答

你能试试使用shift和groupby吗?一旦前一行的所有操作都是直行。在

table2['previous'] = table2['close'].groupby('symbol').shift(1)

table2

date    symbol      close   atr     previous

1990-01-01  A   24  2   NaN
            B   72  7   NaN
            C   40  3.4     NaN
1990-01-02  A   21  1.5     24
            B   65  6   72
            C   45  4.2     40
1990-01-03  A   19  2.5     21
            B   70  6.3     65
            C   51  5   45

这个解决方案当然可以清理,但会产生您想要的输出。我已经在示例数据帧的构造中包含了您的初始条件:

import pandas as pd
import numpy as np

df = pd.DataFrame({'Date': ['1990-01-01','1990-01-01','1990-01-01','1990-01-02','1990-01-02','1990-01-02','1990-01-03','1990-01-03','1990-01-03'],
    'Symbol': ['A','B','C','A','B','C','A','B','C'],
    'Close': [24, 72, 40, 21, 65, 45, 19, 70, 51],
    'ATR': [2, 7, 3.4, 1.5, 6, 4.2, 2.5, 6.3, 5],
    'Shares': [0, 0, 0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
    'Profit': [0, 0, 0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]})

给出:

^{pr2}$

然后使用groupby()apply()并全局跟踪您的{}。我花了一点时间才意识到这个问题的本质要求您分别在两个独立的列上分组(Symbol和{}):

start = 10000
Equity = 10000

def calcs(x):

    global Equity

    if x.index[0]==0: return x #Skip first group

    x['Shares'] = np.floor(Equity*0.02/x['ATR'])
    x['Profit'] = x['Shares']*x['Close']
    Equity += x['Profit'].sum()

    return x

df = df.groupby('Date').apply(calcs)
df['Equity'] = df.groupby('Date')['Profit'].transform('sum')
df['Equity'] = df.groupby('Symbol')['Equity'].cumsum()+start

这就产生了:

         Date Symbol  Close  ATR  Shares  Profit   Equity
0  1990-01-01      A     24  2.0     0.0     0.0  10000.0
1  1990-01-01      B     72  7.0     0.0     0.0  10000.0
2  1990-01-01      C     40  3.4     0.0     0.0  10000.0
3  1990-01-02      A     21  1.5   133.0  2793.0  17053.0
4  1990-01-02      B     65  6.0    33.0  2145.0  17053.0
5  1990-01-02      C     45  4.2    47.0  2115.0  17053.0
6  1990-01-03      A     19  2.5   136.0  2584.0  26885.0
7  1990-01-03      B     70  6.3    54.0  3780.0  26885.0
8  1990-01-03      C     51  5.0    68.0  3468.0  26885.0

相关问题 更多 >

    热门问题