在 Python 中创建一个查看先前 IF 语句输出的 IF 语句

Creating an IF statement in Python that looks at previous IF statement output

我在创建执行以下操作的 IF 语句时遇到困难:

请看下面的例子。我希望创建一个像 'C3' 这样的专栏。

示例数据集:

index  C1    C2
0      Buy   nan
1      nan   nan
2      nan   Sell
3      nan   nan
4      Buy   nan
5      nan   Sell
6      nan   Sell
7      nan   nan
8      nan   nan
9      Buy   nan
10     nan   Sell

输出:

index  C1    C2    C3
0      Buy   nan   Buy
1      nan   nan   Buy
2      nan   Sell  Sell
3      nan   nan   Sell
4      Buy   nan   Buy
5      nan   Sell  Sell
6      nan   Sell  Sell
7      nan   nan   Sell
8      nan   nan   Sell
9      Buy   nan   Buy
10     nan   Sell  Sell

您无需执行前面的 if 语句,只需查看之前放入 c3 列表的内容(因为这是前面 if 语句的结果)。

下面是如何在 python 中实现此目的的示例:

c1 = ["Buy", "nan", "nan", "nan", "Buy", "nan", "nan", "nan", "nan", "Buy", "nan"]
c2 = ["nan", "nan", "Sell", "nan", "nan", "Sell", "Sell", "nan", "nan", "nan", "Sell"]

c3 = []
for index in range(len(c1)):
    if c1[index] == "Buy":
        c3.append("Buy")
    elif c2[index] == "Sell":
        c3.append("Sell")
    elif c1[index] == "nan" and c2[index] == "nan": # Implied if reached this point (so else would also suffice here)
        c3.append(c3[index-1]) # look at previous result in list
print(c3)

输出:

['Buy', 'Buy', 'Sell', 'Sell', 'Buy', 'Sell', 'Sell', 'Sell', 'Sell', 'Buy', 'Sell']

这里有一个使用 Pandas 的简洁方法:将所有 NaN 交换为空字符串,并将 return 交换每行中的任何字符串值。如果一行为空,return 它之前的内容。

import pandas as pd

def decide(data):
    if len(data.sum()):
        return data.sum()
    return decide(df.iloc[data.name - 1])

df.fillna("", inplace=True)
df.apply(decide, axis=1)

输出:

index
0      Buy
1      Buy
2     Sell
3     Sell
4      Buy
5     Sell
6     Sell
7     Sell
8     Sell
9      Buy
10    Sell
dtype: object

注:这里做几个假设。首先,假设只有 BuySell 出现在一行中。其次,假设第一行不为空。

数据:

df = pd.read_clipboard(index_col="index") # copied from OP

您可以使用 pd.DataFrame.ffill along axis=1 followed by pd.Series.ffill:

df['C3'] = df[['C1', 'C2']].ffill(axis=1).iloc[:, -1].ffill()

print(df)

    index   C1    C2    C3
0       0  Buy   NaN   Buy
1       1  NaN   NaN   Buy
2       2  NaN  Sell  Sell
3       3  NaN   NaN  Sell
4       4  Buy   NaN   Buy
5       5  NaN  Sell  Sell
6       6  NaN  Sell  Sell
7       7  NaN   NaN  Sell
8       8  NaN   NaN  Sell
9       9  Buy   NaN   Buy
10     10  NaN  Sell  Sell