匹配最接近的值面板数据 Pandas
Matching closest values panel data Pandas
我目前正在做一个涉及财务数据的项目。我有一个数据框,其中包含许多基本变量以及许多不同公司的股票 returns,就像这样:
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
我一直试图做但没有成功的是,根据同一年最接近的 tot_assets
值,将每一年的每家公司 ticker
与 df 中的另一家公司相匹配.因此创建两个新列,其中一个包含匹配公司的 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 个观察结果 - 但我希望上述概念对您有所帮助 :)
提前致谢!
merge
年内并删除任何与自身合并的代码。然后确定'total_assets'
中的绝对差。通过排序和删除重复项,我们只保留原始 DataFrame 中每个 ['ticker'、'year'] 的最接近匹配项。
示例数据
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
。因为 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'))
我目前正在做一个涉及财务数据的项目。我有一个数据框,其中包含许多基本变量以及许多不同公司的股票 returns,就像这样:
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
我一直试图做但没有成功的是,根据同一年最接近的 tot_assets
值,将每一年的每家公司 ticker
与 df 中的另一家公司相匹配.因此创建两个新列,其中一个包含匹配公司的 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 个观察结果 - 但我希望上述概念对您有所帮助 :)
提前致谢!
merge
年内并删除任何与自身合并的代码。然后确定'total_assets'
中的绝对差。通过排序和删除重复项,我们只保留原始 DataFrame 中每个 ['ticker'、'year'] 的最接近匹配项。
示例数据
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
。因为 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'))