如果condition为true,则填充具有第x行前一行的相反值的行

问题描述 投票:2回答:4

以下是我从以下开始的Dataframe:

import pandas as pd
import numpy as np

d= {'PX_LAST':[1,2,3,3,3,1,2,1,1,1,3,3],'ma':[2,2,2,2,2,2,2,2,2,2,2,2],'action':[0,0,1,0,0,-1,0,1,0,0,-1,0]}
df_zinc = pd.DataFrame(data=d)

df_zinc

Now, I need to add a column called 'buy_sell', which:

  • 当'action'== 1时,如果'PX_LAST'>'ma'则填充1,如果'PX_LAST'<'ma'则填充-1
  • 当'action'== - 1时,填充与之前填充的非零值相反的值

仅供参考:在我的数据中,需要用前一个非零项目的相反方向填充的行总是与前一个非零项目相同的距离(即当前示例中为2)。这应该有助于制作代码。

the code that I made so far is the following. It seems right to me. Do you have any fixes to propose?

 while index < df_zinc.shape[0]:
    if df_zinc['action'][index] == 1:
        if df_zinc['PX_LAST'][index]<df_zinc['ma'][index]:
            df_zinc.loc[index,'buy_sell'] = -1
        else:
            df_zinc.loc[index,'buy_sell'] = 1
    elif df_zinc['action'][index] == -1:
            df_zinc['buy_sell'][index] = df_zinc['buy_sell'][index-3]*-1 
    index=index+1
df_zinc

the resulting dataframe would look like this:

    df_zinc['buy_sell'] = [0,0,1,0,0,-1,0,-1,0,0,1,0]

    df_zinc
python pandas
4个回答
1
投票

所以,根据示例输出,这将是我的建议(假设我理解正确的问题:

def buy_sell(row):
   if row['action'] == 0:
      return 0
   if row['PX_LAST'] > row['ma']:
      return 1 * (-1 if row['action'] == 0 else 1)
   else:
      return -1 * (-1 if row['action'] == 0 else 1)
   return 0

df_zinc = df_zinc.assign(buy_sell=df_zinc.apply(buy_sell, axis=1))      
df_zinc

这应该符合规则的预期。它没有考虑'PX_LAST'等于'ma'的可能性,默认返回0,因为不清楚该场景中应遵循什么规则。

编辑

好的,在新逻辑解释之后,我认为这应该可以解决问题:

def assign_buysell(df):
    last_nonzero = None
    def buy_sell(row):
        nonlocal last_nonzero
        if row['action'] == 0:
            return 0
        if row['action'] == 1:
            if row['PX_LAST'] < row['ma']:
                last_nonzero = -1
            elif row['PX_LAST'] > row['ma']:
                last_nonzero = 1
        elif row['action'] == -1:
            last_nonzero = last_nonzero * -1
        return last_nonzero
    return df.assign(buy_sell=df.apply(buy_sell, axis=1))
df_zinc = assign_buysell(df_zinc)

这个解决方案与多久以前看到的非零值无关,它只记得最后一个非零值并且管道相反的wen动作为-1。


1
投票

您可以使用np.select,并使用np.nan作为满足第三个条件的行的标签:

c1 = df_zinc.action.eq(1) & df_zinc.PX_LAST.gt(df_zinc.ma)
c2 = df_zinc.action.eq(1) & df_zinc.PX_LAST.lt(df_zinc.ma)
c3 = df_zinc.action.eq(-1)

df_zinc['buy_sell'] = np.select([c1,c2, c3], [1, -1, np.nan])

现在为了用上面NaNs行的值填充n(在本例中为3),你可以使用数据帧的移位版本来fillna

df_zinc['buy_sell'] = df_zinc.buy_sell.fillna(df_zinc.buy_sell.shift(3)*-1)

产量

   PX_LAST  ma  action  buy_sell
0         1   2       0       0.0
1         2   2       0       0.0
2         3   2       1       1.0
3         3   2       0       0.0
4         3   2       0       0.0
5         1   2      -1      -1.0
6         2   2       0       0.0
7         1   2       1      -1.0
8         1   2       0       0.0
9         1   2       0       0.0
10        3   2      -1       1.0
11        3   2       0       0.0

0
投票

我会使用np.select,因为你有多个条件:

conditions = [
    (df_zinc['action'] == 1) & (df_zinc['PX_LAST'] > df_zinc['ma']),
    (df_zinc['action'] == 1) & (df_zinc['PX_LAST'] < df_zinc['ma']),
    (df_zinc['action'] == -1) & (df_zinc['PX_LAST'] > df_zinc['ma']),
    (df_zinc['action'] == -1) & (df_zinc['PX_LAST'] < df_zinc['ma'])
]

choices = [1, -1, 1, -1]

df_zinc['buy_sell'] = np.select(conditions, choices, default=0)

结果

print(df_zinc)
    PX_LAST  ma  action  buy_sell
0         1   2       0         0
1         2   2       0         0
2         3   2       1         1
3         3   2       0         0
4         3   2       0         0
5         1   2      -1        -1
6         2   2       0         0
7         1   2       1        -1
8         1   2       0         0
9         1   2       0         0
10        3   2      -1         1
11        3   2       0         0

0
投票

这里我的解决方案使用函数shift()来捕获第3行的数据:

df_zinc['buy_sell'] = 0
df_zinc.loc[(df_zinc['action'] == 1) & (df_zinc['PX_LAST'] < df_zinc['ma']), 'buy_sell'] = -1
df_zinc.loc[(df_zinc['action'] == 1) & (df_zinc['PX_LAST'] > df_zinc['ma']), 'buy_sell'] = 1
df_zinc.loc[df_zinc['action'] == -1, 'buy_sell'] = -df_zinc['buy_sell'].shift(3)
df_zinc['buy_sell'] = df_zinc['buy_sell'].astype(int)

print(df_zinc)

输出:

    PX_LAST  ma  action  buy_sell 
0         1   2       0          0
1         2   2       0          0
2         3   2       1          1
3         3   2       0          0
4         3   2       0          0
5         1   2      -1         -1
6         2   2       0          0
7         1   2       1         -1
8         1   2       0          0
9         1   2       0          0
10        3   2      -1          1
11        3   2       0          0
© www.soinside.com 2019 - 2024. All rights reserved.