создайте новый столбец в фрейме данных pandas, используя условие if из другого фрейма данных

#python #pandas

#python #pandas

Вопрос:

У меня есть два фрейма данных следующим образом

 transactions

    buy_date    buy_price
0   2018-04-16  33.23
1   2018-05-09  33.51
2   2018-07-03  32.74
3   2018-08-02  33.68
4   2019-04-03  33.58
 

и

 cii

    from_fy     to_fy       score
0   2001-04-01  2002-03-31  100
1   2002-04-01  2003-03-31  105
2   2003-04-01  2004-03-31  109
3   2004-04-01  2005-03-31  113
4   2005-04-01  2006-03-31  117
 

В фрейме данных транзакций мне нужно создать новые столбцы cii_score на основе следующего условия

if transactions['buy_date'] находится между cii['from_fy'] и cii['to_fy'] принимает cii['score'] значение для transactions['cii_score']

Я пробовал понимание списка, но это бесполезно.

Запросите ваши входные данные для решения этой проблемы.

Комментарии:

1. можете ли вы опубликовать ожидаемый результат, а также образцы данных, которые действительно можно протестировать?

2. Соответствует ли индекс транзакций индексу cii?

Ответ №1:

Сначала мы настроим вашу dfs. Обратите внимание, что я изменил даты transactions в этом коротком примере, чтобы сделать его более интересным

 import pandas as pd
from io import StringIO
trans_data = StringIO(
    """
,buy_date,buy_price
0,2001-04-16,33.23
1,2001-05-09,33.51
2,2002-07-03,32.74
3,2003-08-02,33.68
4,2003-04-03,33.58
    """
)

cii_data = StringIO(
    """
,from_fy,to_fy,score
0,2001-04-01,2002-03-31,100
1,2002-04-01,2003-03-31,105
2,2003-04-01,2004-03-31,109
3,2004-04-01,2005-03-31,113
4,2005-04-01,2006-03-31,117    
    """
)
tr_df = pd.read_csv(trans_data, index_col = 0)
tr_df['buy_date'] = pd.to_datetime(tr_df['buy_date'])

cii_df = pd.read_csv(cii_data, index_col = 0)
cii_df['from_fy'] = pd.to_datetime(cii_df['from_fy'])
cii_df['to_fy'] = pd.to_datetime(cii_df['to_fy'])
 

Главное — это следующее вычисление: для каждого индекса строки tr_df найдите индекс строки, cii_df которая удовлетворяет условию. Следующее вычисляет это соответствие, каждый элемент списка равен соответствующему индексу строки cii_df :

 match = [ [(f<=d) amp; (d<=e) for f,e in zip(cii_df['from_fy'],cii_df['to_fy']) ].index(True) for d in tr_df['buy_date']]
match
 

производит

 [0, 0, 1, 2, 2]
 

теперь мы можем объединить это

 tr_df.merge(cii_df, left_on = np.array(match), right_index = True)
 

так что мы получаем

 
    key_0 buy_date  buy_price   from_fy to_fy       score
0   0   2001-04-16  33.23   2001-04-01  2002-03-31  100
1   0   2001-05-09  33.51   2001-04-01  2002-03-31  100
2   1   2002-07-03  32.74   2002-04-01  2003-03-31  105
3   2   2003-08-02  33.68   2003-04-01  2004-03-31  109
4   2   2003-04-03  33.58   2003-04-01  2004-03-31  109
 

и score столбец — это то, что вы просили