Фильтровать данные в фреймах данных

#python #pandas #numpy

#python #панды #numpy

Вопрос:

Я пытаюсь создать приложение, которое пытается найти трендовые акции за последние 6 месяцев. Приложение проверяет наличие двух условий, а именно:

  1. Является ли (предыдущее закрытие) < (закрыть) Если да, то возвращается True
  2. Иначе возвращается false.

После определения двух вышеуказанных условий программа проверяет, сколько истинных значений существует последовательно, если существует несколько истинных значений, добавьте 1 к счетчику трендов и добавьте его в виде столбца. Для ложных значений счетчик должен быть установлен как 0.

Код для того же:

 import pandas as pd
from nsepy import get_history
from datetime import date
import sqlalchemy
import numpy as np
stock = ['APLAPOLLO','AUBANK','AARTIDRUGS']
res = dict(zip(stock,stock))
start = date (2020, 6, 14)
end = date (2020, 12, 15)

for stock_name in stock:
     data = get_history(symbol=stock_name, start=start, end=end)
     res[stock_name]=data
for key, df in res.items():
     # create a column called "key name"
     df['key_name'] = key

lst = list(res.values())
df = pd.concat(lst)
df['boolean'] = df['Prev Close'] < df['Close']

a = df['boolean']
b = a.cumsum()
df['trend'] = (b-b.mask(a).ffill().fillna(0).astype(int)).where(a, 0)
 

Результирующий фрейм данных выглядит так, как показано на рисунке:

Фрейм данных

Я хочу изменить одно из условий следующим образом: для данного символа, даже если одно значение встречается как false, присвоите 0 для всех следующих значений в столбце trend для этого конкретного символа.

например: 15/6/2020 Для APLAPOLLO логическое значение равно false, следовательно, в данном фрейме данных я хочу установить значение тренда APLAPOLLO как 0 для всех строк после этой конкретной строки

Ответ №1:

Вообще говоря, вы можете создавать пронумерованные группы ложных записей — истинными записями будут NaN, а затем перенаправлять заполнение, чтобы заполнить истинные записи, которые появляются после ложных записей. Затем просто заполните ваши ранние истинные значения сигнальным значением df[«trend»].fillna(value=1, inplace=True) и используйте where, чтобы заполнить все, кроме ваших стражей, 0.

Этот подход легко адаптируется к ряду различных проблем, связанных с тенденциями, которые имеют логический компонент.

Вот рабочий код — вы можете разделить строки и распечатать данные на каждом шаге, если хотите быть уверенным, что знаете, как это работает:

 import pandas as pd
df = pd.DataFrame({'boolean': [True, True, True, True, False, False, True, True, False, True, False, True]})
# set the condition
trendBasis = ~df['boolean']
# Create numbered groups of False entries - True entries will be NaN
df["trend"] = (~trendBasis).cumsum().where(trendBasis)
#Forward fill to fill in True entries that occur after False entries
df["trend"].fillna(method='pad', inplace=True)
#Fill your early True values with a sentinel value
df["trend"].fillna(value=1, inplace=True)
#Use where to fill everything except your sentinels with 0
df["trend"] = df["trend"].where(df["trend"]==1, 0)
#Profit!
print(df)

    boolean  trend
0      True    1.0
1      True    1.0
2      True    1.0
3      True    1.0
4     False    0.0
5     False    0.0
6      True    0.0
7      True    0.0
8     False    0.0
9      True    0.0
10    False    0.0
11     True    0.0