#python #pandas
#питон #pandas
Вопрос:
У меня есть фрейм данных ниже:
ticker date buy_fg sell_fg
50 ABC 2010-01-01 0.0 2.0
51 ABC 2010-01-08 0.0 2.0
52 ABC 2010-01-15 0.0 2.0
53 ABC 2010-01-22 0.0 2.0
1512 ABC 2010-01-29 1.0 0.0
54 ABC 2010-02-05 0.0 2.0
55 ABC 2010-02-12 0.0 2.0
56 ABC 2010-02-19 0.0 2.0
57 ABC 2010-02-26 0.0 2.0
58 ABC 2010-03-05 0.0 2.0
59 ABC 2010-03-12 0.0 2.0
60 ABC 2010-03-19 0.0 2.0
61 ABC 2010-03-26 0.0 2.0
1417 ABC 2010-04-02 1.0 0.0
1409 ABC 2010-04-09 1.0 0.0
62 ABC 2010-04-23 0.0 2.0
63 ABC 2010-05-07 0.0 2.0
64 ABC 2010-05-14 0.0 2.0
65 ABC 2010-05-21 0.0 2.0
66 ABC 2010-05-28 0.0 2.0
Я пытаюсь разработать колонку, в которой содержится краткое описание действий, которые должен выполнить мой сценарий. Я пытался разработать подход с накопительной оценкой и не смог заставить его работать. Я также пробовал lambda, однако логика неверна, поскольку она просто повторяет buy_fg
столбец.
# Initiate the global, default buy flag
hold_flag = False
# Custom function to flick the global flag based on `buy_fg` column
def hold(value):
global hold_flag
if value == 1:
if hold_flag is False:
hold_flag = True
return '3'
if hold_flag is True:
hold_flag = False
return '1'
else:
return '0'
new_report['hold_fg'] = new_report['buy_fg'].apply(hold)
Это создало hold_fg
столбец. Но теперь мне нужно расширить это, чтобы рассмотреть все три *_fg
столбца, чтобы обеспечить окончательное действие.
ticker date buy_fg sell_fg action hold_fg
50 ABC 2010-01-01 0.0 2.0 0 0
51 ABC 2010-01-08 0.0 2.0 0 0
52 ABC 2010-01-15 0.0 2.0 0 0
53 ABC 2010-01-22 0.0 2.0 0 0
1512 ABC 2010-01-29 1.0 0.0 0 1
54 ABC 2010-02-05 0.0 2.0 0 0
55 ABC 2010-02-12 0.0 2.0 0 0
56 ABC 2010-02-19 0.0 2.0 0 0
57 ABC 2010-02-26 0.0 2.0 0 0
58 ABC 2010-03-05 0.0 2.0 0 0
59 ABC 2010-03-12 0.0 2.0 0 0
60 ABC 2010-03-19 0.0 2.0 0 0
61 ABC 2010-03-26 0.0 2.0 0 0
1417 ABC 2010-04-02 1.0 0.0 0 1
1409 ABC 2010-04-09 1.0 0.0 0 3
62 ABC 2010-04-23 0.0 2.0 0 0
63 ABC 2010-05-07 0.0 2.0 0 0
64 ABC 2010-05-14 0.0 2.0 0 0
65 ABC 2010-05-21 0.0 2.0 0 0
66 ABC 2010-05-28 0.0 2.0 0 0
Я пробовал следующее, но это не работает:
new_report['action'] = 0
buy_flag = False
def action(value):
global buy_flag
if new_report['hold_fg'] == 1:
buy_flag = True
return 'BUY'
if new_report['hold_fg'] == 3:
buy_flag = True
return 'HOLD'
if new_report['sell_fg'] == 2:
buy_flag = False
return 'SELL'
else:
return '0'
Есть идеи о том, как я могу это решить?
обновлен ожидаемый результат:
ticker date buy_fg sell_fg action hold_fg
50 ABC 2010-01-01 0.0 2.0 NIL 0
51 ABC 2010-01-08 0.0 2.0 NIL 0
52 ABC 2010-01-15 0.0 2.0 NIL 0
53 ABC 2010-01-22 0.0 2.0 NIL 0
1512 ABC 2010-01-29 1.0 0.0 BUY 1
54 ABC 2010-02-05 0.0 2.0 SELL 0
55 ABC 2010-02-12 0.0 2.0 NIL 0
56 ABC 2010-02-19 0.0 2.0 NIL 0
57 ABC 2010-02-26 0.0 2.0 NIL 0
58 ABC 2010-03-05 0.0 2.0 NIL 0
59 ABC 2010-03-12 0.0 2.0 NIL 0
60 ABC 2010-03-19 0.0 2.0 NIL 0
61 ABC 2010-03-26 0.0 2.0 NIL 0
1417 ABC 2010-04-02 1.0 0.0 BUY 1
1409 ABC 2010-04-09 1.0 0.0 HOLD 3
62 ABC 2010-04-23 0.0 2.0 SELL 0
63 ABC 2010-05-07 0.0 2.0 NIL 0
64 ABC 2010-05-14 0.0 2.0 NIL 0
65 ABC 2010-05-21 0.0 2.0 NIL 0
66 ABC 2010-05-28 0.0 2.0 NIL 0
Комментарии:
1. судя по вашей
action
колонке, вы на правильном пути, но я не могу понять ваш вопрос: чего именно вам сейчас не хватает?2. Это немного сбивает с толку. Не могли бы вы подробнее остановиться на этом
it needs to show a 'SELL' only when a 'BUY has been registered'
? Какой ожидаемый результат вы ищете?3. Обновлено с учетом логики и ожидаемого результата.
4. Поскольку вы обновили / изменили вопрос, можете ли вы также снова обновить ожидаемый результат?
5. Обновлено — единственное отличие от вашего обновленного решения — индексы 1417, 1409 и 62
Ответ №1:
Я думаю, вам нужно будет отслеживать статус и применять требуемую логику на основе этого. Вот пример использования пользовательской функции для этого. Надеюсь, это поможет!
# Initiate the global, default buy flag
>>> buy_flag = False
# Custom function to flick the global flag based on `buy_fg` column
>>> def sell_or_buy(value):
global buy_flag
if value == 1:
if buy_flag is False:
buy_flag = True
return 'BUY'
if buy_flag is True:
return 'HOLD'
if value == 0:
if buy_flag == 1:
buy_flag = False
return 'SELL'
if buy_flag == 0:
return 'NIL'
>>> df['action'] = df['buy_fg'].apply(sell_or_buy)
>>> df
ticker date buy_fg sell_fg action
0 50 ABC 2010-01-01 0.0 2.0 NIL
1 51 ABC 2010-01-08 0.0 2.0 NIL
2 52 ABC 2010-01-15 0.0 2.0 NIL
3 53 ABC 2010-01-22 0.0 2.0 NIL
4 1512 ABC 2010-01-29 1.0 0.0 BUY
5 54 ABC 2010-02-05 0.0 2.0 SELL
6 55 ABC 2010-02-12 0.0 2.0 NIL
7 56 ABC 2010-02-19 0.0 2.0 NIL
8 57 ABC 2010-02-26 0.0 2.0 NIL
9 58 ABC 2010-03-05 0.0 2.0 NIL
10 59 ABC 2010-03-12 0.0 2.0 NIL
11 60 ABC 2010-03-19 0.0 2.0 NIL
12 61 ABC 2010-03-26 0.0 2.0 NIL
13 1417 ABC 2010-04-02 1.0 0.0 BUY
14 1409 ABC 2010-04-09 1.0 0.0 HOLD
15 62 ABC 2010-04-23 0.0 2.0 SELL
16 63 ABC 2010-05-07 0.0 2.0 NIL
17 64 ABC 2010-05-14 0.0 2.0 NIL
18 65 ABC 2010-05-21 0.0 2.0 NIL
19 66 ABC 2010-05-28 0.0 2.0 NIL
Редактировать:
Это сделано для удовлетворения ваших последних требований. Поскольку из-за того, как вы обновили вопрос, он становится немного запутанным, я просто изменю свой ответ, чтобы добавить его к приведенному выше фрейму данных.
>>> d={'NIL': 0, 'BUY': 1, 'SELL': 2, 'HOLD' : 3}
>>> df['hold_fg'] = df.action.map(d)
>>> df
ticker date buy_fg sell_fg action hold_fg
0 50 ABC 2010-01-01 0.0 2.0 NIL 0
1 51 ABC 2010-01-08 0.0 2.0 NIL 0
2 52 ABC 2010-01-15 0.0 2.0 NIL 0
3 53 ABC 2010-01-22 0.0 2.0 NIL 0
4 1512 ABC 2010-01-29 1.0 0.0 BUY 1
5 54 ABC 2010-02-05 0.0 2.0 SELL 2
6 55 ABC 2010-02-12 0.0 2.0 NIL 0
7 56 ABC 2010-02-19 0.0 2.0 NIL 0
8 57 ABC 2010-02-26 0.0 2.0 NIL 0
9 58 ABC 2010-03-05 0.0 2.0 NIL 0
10 59 ABC 2010-03-12 0.0 2.0 NIL 0
11 60 ABC 2010-03-19 0.0 2.0 NIL 0
12 61 ABC 2010-03-26 0.0 2.0 NIL 0
13 1417 ABC 2010-04-02 1.0 0.0 BUY 1
14 1409 ABC 2010-04-09 1.0 0.0 HOLD 3
15 62 ABC 2010-04-23 0.0 2.0 SELL 2
16 63 ABC 2010-05-07 0.0 2.0 NIL 0
17 64 ABC 2010-05-14 0.0 2.0 NIL 0
18 65 ABC 2010-05-21 0.0 2.0 NIL 0
19 66 ABC 2010-05-28 0.0 2.0 NIL 0
Комментарии:
1. Спасибо, это помогло мне приблизиться на один шаг, но я дополнил вопрос некоторыми последующими задачами.
2. Эй, не беспокойтесь, я посмотрю, но вам не следовало обновлять свой первоначальный вопрос, поскольку теперь он делает мой ответ совершенно бесполезным, поскольку он делает то, что вам было нужно / о чем вы просили изначально, и в основном аннулирует мой ответ здесь (представьте себе кого-то, кто читает это впервые — мой ответ будетбыть полностью недействительным, в чем вопрос)… Я посмотрю на вашу логику, но я предложу вернуть ваш вопрос и сохранить историю. Таким образом, другие люди могут предложить вам еще лучшее общее решение. Лучше всего, если вы будете задавать по 1 вопросу за раз.. Надеюсь, это имеет смысл