为了账号安全,请及时绑定邮箱和手机立即绑定

要锁定的数据帧单元格,并用于运行余额计算的条件是同一行上另一个单元格的结果

要锁定的数据帧单元格,并用于运行余额计算的条件是同一行上另一个单元格的结果

慕妹3242003 2022-08-11 20:16:49
假设我有以下数据帧:import pandas as pddf = pd.DataFrame()df['A'] = ('1/05/2019','2/05/2019','3/05/2019','4/05/2019','5/05/2019','6/05/2019','7/05/2019','8/05/2019','9/05/2019','10/05/2019','11/05/2019','12/05/2019','13/05/2019','14/05/2019','15/05/2019','16/05/2019','17/05/2019','18/05/2019','19/05/2019','20/05/2019')df['B'] = ('SIT','SCLOSE', 'SHODL', 'SHODL', 'SHODL', 'SHODL', 'SHODL', 'SELL','SIT','SIT','BCLOSE', 'BHODL', 'BHODL', 'BHODL', 'BHODL', 'BHODL', 'BHODL','BUY','SIT','SIT')df['C'] = (0.00,1.00,10.00, 5.00,6.00,-6.00, 6.00, 0.00,0.00,0.00,-8.00,33.00,-15.00,6.00,-1.00,5.00,10.00,0.00,0.00,0.00)df.loc[19, 'D'] = 100.0000可以看出,我从最后一行的100开始D列。我正在尝试为列D编写计算代码,因此从底部行(第19行)开始,当B列上显示买入或卖出时,D列上的数字被锁定(例如100),并用于基于每个SHODL或BHODL的col C的计算,直到显示BCLOSE或SCLOSE之后的行。锁定的数字用于根据列 C 中的百分比计算运行余额。如您在第 16 行中看到的,C 列的“10”表示 10%。当 100 的 10% = 10 时,新的运行平衡为 110。第 15 行 C 列有 5%,因此将 5 添加到运行余额中以产生 115。下一行 14 列 C 具有 -1% 的变化,因为 100 的 1% 是 = 1,因此新的运行余额是 114,依此类推。以下是运行正确的代码后,应在数据帧的 col D 中返回的结果df['D'] = ('158.60','158.60', '157.30', '144.30', '137.80', '130.00', '137.80', '130.00','130.00','130.00','130.00', '138.00', '105.00', '120.00', '114.00', '115.00', '110.00','100.00','100.00','100.00')这种情况一直持续到 SCLOSE 或 BCLOSE 显示为 BCLOSE 或 SCLOSE 行是计算运行余额的最后一行。如您所见,当显示新的买入或卖出时,此过程将重新启动。
查看完整描述

3 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

下一个起始值取决于上一组的最后一个值,因此我认为它无法矢量化。它需要某种迭代过程。我想出了在groupby的组上进行迭代的解决方案。反转并分配给 。处理每组组并将最终组列表分配给原始组dfdf1df1df


df1 = df[::-1]

s = df1.B.isin(['BCLOSE','SCLOSE']).shift(fill_value=False).cumsum()

grps = df1.groupby(s)

init_val= 100

l = []

for _, grp in grps:

    s = grp.C * 0.01 * init_val

    s.iloc[0] = init_val

    s = s.cumsum()

    init_val = s.iloc[-1]

    l.append(s)


df['D'] = pd.concat(l)


Out[50]:

             A       B     C      D

0    1/05/2019     SIT   0.0  158.6

1    2/05/2019  SCLOSE   1.0  158.6

2    3/05/2019   SHODL  10.0  157.3

3    4/05/2019   SHODL   5.0  144.3

4    5/05/2019   SHODL   6.0  137.8

5    6/05/2019   SHODL  -6.0  130.0

6    7/05/2019   SHODL   6.0  137.8

7    8/05/2019    SELL   0.0  130.0

8    9/05/2019     SIT   0.0  130.0

9   10/05/2019     SIT   0.0  130.0

10  11/05/2019  BCLOSE  -8.0  130.0

11  12/05/2019   BHODL  33.0  138.0

12  13/05/2019   BHODL -15.0  105.0

13  14/05/2019   BHODL   6.0  120.0

14  15/05/2019   BHODL  -1.0  114.0

15  16/05/2019   BHODL   5.0  115.0

16  17/05/2019   BHODL  10.0  110.0

17  18/05/2019     BUY   0.0  100.0

18  19/05/2019     SIT   0.0  100.0

19  20/05/2019     SIT   0.0  100.0        


查看完整回答
反对 回复 2022-08-11
?
慕斯王

TA贡献1864条经验 获得超2个赞

下面的这篇文章应该可以帮助你。它产生预期的输出,并且速度相对较快,因为它避免了对数据帧行的直接迭代。


endpoints = [df.first_valid_index(), df.last_valid_index()]

# occurrences of 'BCLOSE' or 'SCLOSE'

breakpoints = df.index[(df.B =='BCLOSE') | (df.B == 'SCLOSE')][::-1]

# remove the endpoints of the dataframe that do not break the structure

breakpoints = breakpoints.drop(endpoints, errors='ignore')


PERCENTAGE_CONST = 100

top = 100  # you can specify any initial value here


for i in range(len(breakpoints) + 1):


    prv = breakpoints[i - 1] - 1 if i else -1  # previous or first breakpoint

    try:

        nex = breakpoints[i] - 1  # next breakpoint

    except IndexError:

        nex = None  # last breakpoint


    # cumulative sum of appended to 'D' column

    res = top + (df['C'][prv: nex: -1] * top / PERCENTAGE_CONST).cumsum()[::-1]

    df.loc[res.index, 'D'] = res


    # saving the value that will be the basis for percentage calculations

    # for the next breakpoint

    top = res.iloc[0]


查看完整回答
反对 回复 2022-08-11
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

我认为有一种更优化和pythonic的方法可以解决这个问题。但是一个带有迭代的解决方案:


df['D'] = pd.to_numeric(df['D'])

df['C'] = pd.to_numeric(df['C'])

D_val = None

for i in range(len(df)-1, 0, -1):

    if df.loc[i, 'B'] == 'BUY':

        D_val = df.loc[i, 'D']

        continue

    if D_val is None:

        continue

    df.loc[i, 'D'] = df.loc[i+1, 'D'] + (D_val * df.loc[i, 'C']/100)

每次遇到 in 时,您都会更新 .我们还可以有一个停止的条件,如OP所提到的,如 或 。BUYcolumn DD_valSCLOSEBCLOSE


查看完整回答
反对 回复 2022-08-11
  • 3 回答
  • 0 关注
  • 98 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信