python-3.x 检查 Dataframe 值中条件性的第一次出现

wtlkbnrh  于 2023-01-18  发布在  Python
关注(0)|答案(4)|浏览(170)

我有一个示例 Dataframe (df)如下:

Date_Time      Open      High       Low     Close   UOD  VWB
20  2020-07-01 10:30:00  10298.85  10299.90  10287.85  10299.90    UP    3
21  2020-07-01 10:35:00  10301.40  10310.00  10299.15  10305.75    UP    3
22  2020-07-01 10:40:00  10305.75  10305.75  10285.50  10290.00  DOWN    3
24  2020-07-01 10:45:00  10290.00  10291.20  10277.65  10282.65  DOWN    0
25  2020-07-01 10:50:00  10282.30  10289.80  10278.00  10282.00  DOWN    3
26  2020-07-01 10:55:00  10280.10  10295.00  10279.80  10291.50    UP    3
27  2020-07-01 11:00:00  10290.00  10299.95  10287.30  10297.55    UP    3
28  2020-07-01 11:05:00  10296.70  10306.30  10294.50  10299.40    UP    3
29  2020-07-01 11:10:00  10299.95  10301.10  10291.50  10292.00  DOWN    0
30  2020-07-01 11:15:00  10293.05  10298.70  10286.00  10291.55  DOWN    3
31  2020-07-01 11:20:00  10292.00  10298.70  10286.00  10351.45  DOWN    1

我有以下条件:
1.检查df['VWB'] == 0和df['UOD'] ==“DOWN”,并获取相应的Open值(在我的示例中为10290.00)
1.然后查找该行之后第一个大于此Open值(10290.00)的Close值。
我想要我想要的输出如下与有效列

Date_Time      Open      High       Low     Close   UOD  VWB  Valid
20  2020-07-01 10:30:00  10298.85  10299.90  10287.85  10299.90    UP    3      0
21  2020-07-01 10:35:00  10301.40  10310.00  10299.15  10305.75    UP    3      0
22  2020-07-01 10:40:00  10305.75  10305.75  10285.50  10290.00  DOWN    3      0
23  2020-07-01 10:45:00  10290.00  10291.20  10277.65  10282.65  DOWN    0      0
25  2020-07-01 10:50:00  10282.30  10289.80  10278.00  10282.00  DOWN    3      0
26  2020-07-01 10:55:00  10280.10  10295.00  10279.80  10291.50    UP    3      1 <<= first occurrence
27  2020-07-01 11:00:00  10290.00  10299.95  10287.30  10297.55    UP    3      0
28  2020-07-01 11:05:00  10296.70  10306.30  10294.50  10299.40    UP    3      0
29  2020-07-01 11:10:00  10299.95  10301.10  10291.50  10292.00  DOWN    0      0
30  2020-07-01 11:15:00  10293.05  10298.70  10286.00  10291.55  DOWN    3      0
31  2020-07-01 11:20:00  10292.00  10298.70  10286.00  10351.45  DOWN    1      1 <<= first occurrence
fkvaft9z

fkvaft9z1#

这是一个小技巧,因为我假设有可能有多个值与以下布尔值。

df.loc[(df["VWB"] == 0) & (df["UOD"] == "DOWN")]

我们可以创建一个伪密钥,通过矢量化操作来捕获每个组。
我已经编辑了你的样本,所以我们有2个值,可以等同于上述布尔真。
x一个一个一个一个x一个一个二个x
现在,对于每个组,我们需要比较Open的第一个示例,并查看Close在何处较大。

idx = df1.assign(tempOpen=df1.groupby("key")["Open"].transform("first")).query(
    "Close > tempOpen"
).groupby("key", as_index=False)["key"].idxmin()

df['valid'] = np.where(df1.index.isin(idx) & df1.key.ne(0),1,0)

print(df[['Open','Close','valid']])

       Open     Close  valid
0  10298.85  10299.90      0
1  10301.40  10305.75      0
2  10305.75  10290.00      0
3  10290.00  10282.65      0
4  10282.30  10282.00      0
5  10280.10  10291.50      1
6  10290.00  10297.55      0
7  10296.70  10299.40      0
8  10299.95  10292.00      0
9  10293.05  10595.55      1
k97glaaz

k97glaaz2#

试试看:

df['Val'] = 0
# 1st condition
open_val = df.loc[(df['VWB'].eq(0)) & (df['UOD'].eq("DOWN"))]['Open'].values[0]
u = df.loc[(df['Close'] > open_val)]
# 2nd condition
pos = u.iloc[(u['Close'] - open_val).argsort()[0]]

df.loc[pos,'Val'] = 1
Date_Time      Open      High       Low     Close   UOD  VWB  Val
20 2020-07-01 10:30:00  10298.85  10299.90  10287.85  10299.90    UP    3    0
21 2020-07-01 10:35:00  10301.40  10310.00  10299.15  10305.75    UP    3    0
22 2020-07-01 10:40:00  10305.75  10305.75  10285.50  10290.00  DOWN    3    0
24 2020-07-01 10:45:00  10290.00  10291.20  10277.65  10282.65  DOWN    0    0
25 2020-07-01 10:50:00  10282.30  10289.80  10278.00  10282.00  DOWN    3    0
26 2020-07-01 10:55:00  10280.10  10295.00  10279.80  10291.50    UP    3    1
27 2020-07-01 11:00:00  10290.00  10299.95  10287.30  10297.55    UP    3    0
28 2020-07-01 11:05:00  10296.70  10306.30  10294.50  10299.40    UP    3    0
29 2020-07-01 11:10:00  10299.95  10301.10  10291.50  10292.00  DOWN    3    0
30 2020-07-01 11:15:00  10293.05  10298.70  10286.00  10291.55  DOWN    3    0
bjg7j2ky

bjg7j2ky3#

您可以使用apply遵循此方法:

def valid_column(df):
    max_val = max(df['Open']) + 1
    min_open = max_val

    def find_valid(row):
        global min_open
        if min_open < max_val and row['Close'] > min_open:
            min_open = max_val
            return 1
        if row['VWB'] == 0 and row['UOD'] == "DOWN":
            min_open = min(min_open, row['Open'])
        return 0

    return df.apply(find_valid, axis=1)

df['Valid'] = valid_column(df)

您只需遍历数据集一次,并且使用apply函数,这非常高效。
变量min_open跟踪最小的“Open”值。如果任何行的“Close”值大于该值,则返回1并重置min_open
请注意,这种方法的一个缺点是使用了global关键字,这意味着您的代码中不能有另一个同名的变量。

c9x0cxw0

c9x0cxw04#

对于Umar的好答案,有一个小问题是numpy希望在多个条件句周围加上括号:

df['valid'] = np.where(df1.index.isin(idx) & df1.key.ne(0),1,0)

// should be:

df['valid'] = np.where((df1.index.isin(idx['key'])) & (df1.key.ne(0)), 1, 0)

相关问题