如果条件为tru,则使用上一行的相反值填充行

2024-04-16 06:47:42 发布

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

以下是我开始使用的数据帧:

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

现在,我需要添加一个名为“buy\u sell”的列,它是:

  • 当'action'==1时,如果'PX\u LAST'>;'ma',则填充1,如果'PX\u LAST'<;'ma',则填充-1
  • 当'action'==-1时,使用与先前填充的非零值相反的值填充

仅供参考:在我的数据中,需要填充前一个非零值项的对立面的行与前一个非零值项的距离总是相同的(即当前示例中的2)。这应该有助于制定代码。你知道吗

到目前为止,我编写的代码如下。在我看来是对的。你有什么建议吗?

 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

生成的数据帧如下所示:

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

    df_zinc

Tags: 数据代码importdfindexifasaction
3条回答

您可以使用^{},并使用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])

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

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

我将使用^{},因为您有多个条件:

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

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

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\u 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)

这个解与非零值出现的时间无关,它只记住最后一个非零值,相反的动作是-1。你知道吗

相关问题 更多 >