Для l oop, чтобы найти строки в другом кадре данных - PullRequest
2 голосов
/ 06 февраля 2020

У меня есть два фрейма данных: один с ежедневными ценами на акции (например, все американские акции) и другой с историческими составляющими индекса (например, S & P 500).

Мне удалось создать для l oop который проверяет, была ли каждая акция, каждый день частью индекса. Тем не менее, для l oop может потребоваться много времени, потому что дневные цены DF имеют 65 000 000 строк, а исторические составляющие DF имеют 15 000 строк. Я попытался с некоторыми подмножествами DF, и код делает то, что мне нужно, но это займет несколько дней. Скорость циклов постепенно уменьшается с увеличением итерации, поэтому я думаю, что могу делать что-то очень неэффективно.

DF1: цены закрытия

  ticker date  price
1 AAPL   2018  150.10
2 AAPL   2019  220.50
3 MSFT   2018  50.60
4 MSFT   2019  70.90

DF2: составляющие

  ticker date
1 AMZN   2018
2 AAPL   2018
3 FB     2018
3 AMZN   2019
4 AAPL   2019
5 MSFT   2019

Желаемый результат:

  ticker date  price   in_index
1 AAPL   2018  150.10  yes
2 AAPL   2019  220.50  yes
3 MSFT   2018  50.60   no
4 MSFT   2019  70.90   yes

Итак, в 2018 году AAPL является частью индекса, а MSFT нет. И 2019, и AAPL, и MSFT являются частью индекса.

Вот мой код:

DF1['in_index'] = "no"

for row in range(len(DF1)):

    ticker = DF1.loc[row].ticker
    year = DF1.loc[row].year

    aux = DF2[(DF2.tic==ticker) & (DF2.year==year)]


    if len(aux) > 0:
        DF1['in_index'].loc[row] = 1

Есть ли способ сделать этот l oop более эффективным?

Ответы [ 2 ]

2 голосов
/ 06 февраля 2020

Используйте DataFrame.merge с indicator = True и DataFrame.replace с использованием столбца _merge.

new_df = (df1.merge(df2,on = ['ticker','date'],how = 'left',indicator = 'in_index')
             .replace({'in_index':{'both':'yes','left_only':'no'}})
             )
print(new_df)
  ticker  date  price in_index
0   AAPL  2018  150.1      yes
1   AAPL  2019  220.5      yes
2   MSFT  2018   50.6       no
3   MSFT  2019   70.9      yes
2 голосов
/ 06 февраля 2020

В одну сторону, используя pandas.DataFrame.merge:

new_df = df.merge(df2.assign(in_index="yes"), 
                  on=['ticker','date'], how='left').fillna({'in_index':'no'})
print(new_df)

Вывод:

  ticker  date  price in_index
0   AAPL  2018  150.1      yes
1   AAPL  2019  220.5      yes
2   MSFT  2018   50.6       no
3   MSFT  2019   70.9      yes
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...