Данные панели соответствия ближайших значений Pandas - PullRequest
0 голосов
/ 08 апреля 2020

В настоящее время я работаю над проектом, связанным с финансовыми данными. У меня есть фрейм данных, содержащий ряд фундаментальных переменных, а также доходность акций для разных компаний, например:

           year     ticker      tot_assets      return
0          1999       AAPL          10.345      0.1294
1          2000       AAPL          10.988      0.1577
2          2001       AAPL          12.003      0.0782
..          ...        ...             ...         ...
34521      2017       GMBO           0.893      0.2209
34522      2018       GMBO           1.206      0.1001
..          ...        ...             ...         ...
200344     2012         ZZ           3.789      0.0032
200344     2013         ZZ           3.021     -0.0346

То, что я пытался сделать без успеха, - это сопоставить каждую компанию ticker, для каждого года, с другим в df на основе ближайшего значения tot_assets в том же году. Таким образом, создайте две новые колонки, в которых у каждого есть ticker соответствующей компании, а также returns на тот год.

Таким образом, это должно выглядеть примерно так:

           year     ticker   tot_assets   return   m_ticker   m_return
0          1999       AAPL       10.345   0.1294         AA     0.0890
1          2000       AAPL       10.988   0.1577         AA     0.1666
2          2001       AAPL       12.003   0.0782       TSLA     0.3470
..          ...        ...          ...      ...        ...        ...
34521      2017       GMBO        0.893   0.2209        AIR     0.0032
34522      2018       GMBO        1.206   0.1001       CECE     0.1123
..          ...        ...          ...      ...        ...        ...
200344     2012         ZZ        3.789   0.0032       ASKI     0.0432
200344     2013         ZZ        3.021  -0.0346       ASKI     0.0339

Надеюсь, я был достаточно ясен в своем объяснении: P Возможно, именно поэтому у меня были проблемы! Я не могу показать вам df, потому что он имеет более 200 000 наблюдений - но я надеюсь, что приведенные выше концепции помогут:)

Заранее спасибо!

1 Ответ

2 голосов
/ 08 апреля 2020

merge в течение года и удалите все тикеры, которые слились с собой. Затем определите абсолютную разницу в 'total_assets'. Сортируя и отбрасывая дубликаты, мы сохраняем только самое близкое совпадение для каждого ['тикера', 'года'] в исходном кадре данных.

Пример данных

           year     ticker      tot_assets      return
0          1999       AAPL          10.345      0.1294
1          2000       AAPL          10.988      0.1577
34521      1999       GMBO           0.893      0.2209
34522      2000       GMBO           1.206      0.1001
200344     1999         ZZ           3.789      0.0032
200344     2000         ZZ           3.021     -0.0346

Код

df = df.merge(df, on='year', suffixes=['', '_closest']).query('ticker != ticker_closest')
df['diff'] = (df['tot_assets'] - df['tot_assets_closest']).abs()
df = df.sort_values('diff').drop_duplicates(['year', 'ticker'])

Вывод:

    year ticker  tot_assets  return ticker_closest  tot_assets_closest  return_closest   diff
14  2000   GMBO       1.206  0.1001             ZZ               3.021         -0.0346  1.815
16  2000     ZZ       3.021 -0.0346           GMBO               1.206          0.1001  1.815
5   1999   GMBO       0.893  0.2209             ZZ               3.789          0.0032  2.896
7   1999     ZZ       3.789  0.0032           GMBO               0.893          0.2209  2.896
2   1999   AAPL      10.345  0.1294             ZZ               3.789          0.0032  6.556
11  2000   AAPL      10.988  0.1577             ZZ               3.021         -0.0346  7.967

Выше будет очень большое слияние. Другой альтернативой является использование pd.merge_asof с allow_exact_matches=False. Becasue tot_assets - это число с плавающей точкой, поэтому маловероятно, что два разных тикера будут иметь одинаковое значение, поэтому allow_exact_matches=False, по существу, предотвращает слияние одного и того же тикера с самим собой. Однако, если есть другой тикер с точно таким же Tot_assets, мы пропустим это с помощью этого метода.

df = df.sort_values('tot_assets')
df = (pd.merge_asof(df, df.add_suffix('_closest'), 
                    left_by='year', right_by='year_closest',
                    left_on='tot_assets', right_on='tot_assets_closest',
                    direction='nearest',
                    allow_exact_matches=False)
        .drop(columns='year_closest'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...