如何将数据框中的值分配给在另一个数据框中创建的十分位数?
Posted
技术标签:
【中文标题】如何将数据框中的值分配给在另一个数据框中创建的十分位数?【英文标题】:How do I assign values from a dataframe to deciles created in another dataframe? 【发布时间】:2021-12-31 14:17:54 【问题描述】:我正在使用两个数据框:
df
包含一列 be/me
用于 20 年期间(每月)的股票。
df2
,df
的子集(仅包含某些股票,仅适用于 6 月)包含 decile
列,通过 pd.qcut()
方法创建,基于 @ 的更改版本,在 20 年期间的每一年987654327@的be/me
。
考虑到我在df2
中创建的十分位数,我想知道是否可以根据df2
的decile
列对df
的be/me
进行排名。换句话说,我想知道是否可以将df
的be/me
值分配给df2
中创建的十分位数。
请参阅下面的数据框以更好地了解该问题:
df
date stock_id be/me
2000-01-31 1004.0 0.3
2000-02-29 1004.0 0.7
2000-03-31 1004.0 1.2
2000-04-30 1004.0 2.3
2000-05-31 1004.0 0.9
... ... ...
2020-12-31 3900.0 1.7
2020-12-31 3900.0 2.8
2020-12-31 3900.0 3.0
2020-12-31 3900.0 0.2
2020-12-31 3900.0 2.1
1218855 rows × 3 columns
df2['deciles'] = df2.groupby('date')['be/me'].transform(lambda x: pd.qcut(x, 10, labels=False, duplicates = 'drop'))
df2
date stock_id be/me deciles
2000-06-30 2061.0 0.653684 5
2000-06-30 4383.0 0.053660 2
2000-06-30 13561.0 0.092509 2
2000-06-30 4065.0 1.342187 6
2000-06-30 2731.0 0.235582 3
... ... ... ...
2020-06-30 7022.0 0.072534 2
2020-06-30 30990.0 1.071096 6
2020-06-30 22867.0 1.627155 6
2020-06-30 15247.0 0.051387 2
2020-06-30 61574.0 1.684690 6
24095 rows × 4 columns
注意:date
的类型为 datetime
,并且对于每个日期,都有多个股票 (stock_id
)。
非常感谢您的宝贵时间。
编辑
我想要做的是检查df2
-created 原始be/me
值(来自原始数据框df
)适合哪个十分位。预期的输出应该是df
中的一个新列,df2
创建的十分位数归因于df
中的每个be/me
值。
如果需要任何额外的说明,请告诉我。
我创建了一个函数,该函数循环遍历十分位数以获取df2
中每个date
的最大十分位数。不确定我是否朝着正确的方向前进,因为输出是一个没有 date
的数组...看看下面:
In: def attribution(deciles,dates):
deciles = df2['deciles'].unique()
dates = df2.index.unique()
body_max = []
body_min = []
for x in deciles:
for y in dates:
body_max.append(df2[df2['deciles'] == x].loc[y]['be/me'].max())
body_min.append(df2[df2['deciles'] == x].loc[y]['be/me'].min())
return body_max, body_min
In: attribution(deciles, dates)
Out: [0.9343106070197438,
1.2747264875802489,
1.9700461181925901,
0.7888946814157697,
0.9304702071896337,
0.9651423313922733,
0.7238677612487585,
1.0358317574924074,
...]
【问题讨论】:
能否添加一个包含预期输出的示例数据框? 请参阅上面的编辑,@user17242583。谢谢。 【参考方案1】:要明确:您想知道df
中的每个be/me
值如果该值在df2
中会落入哪个十分位?我看到两种情况:
如果df2
涵盖整个六月(如您所写),恐怕这个问题没有答案:该月中的每一天都会有不同边缘的十分位数箱(因为您正在做一个@987654326 @ 上df2
)。 df
中的相同 be/me
值可能属于 df2
中的不同十分位数,具体取决于您考虑的六月日期。
如果df2
实际上只涵盖 6 月的一天(如您上面的示例所示:2020-06-30
),那么您有一组定义明确的十分位箱。
在情况 2) 中,您可以这样做:
df
date stock_od be/me
0 2000-01-31 1004.0 0.3
1 2000-02-29 1004.0 0.7
2 2000-03-31 1004.0 1.2
3 2000-04-30 1004.0 2.3
4 2000-05-31 1004.0 0.9
5 2020-12-31 3900.0 1.7
6 2020-12-31 3900.0 2.8
7 2020-12-31 3900.0 3.0
8 2020-12-31 3900.0 0.2
9 2020-12-31 3900.0 2.1
df2
date stock_id be/me
0 2000-06-30 2061.0 0.653684
1 2000-06-30 4383.0 0.053660
2 2000-06-30 13561.0 0.092509
3 2000-06-30 4065.0 1.342187
4 2000-06-30 2731.0 0.235582
5 2000-06-30 7022.0 0.072534
6 2000-06-30 30990.0 1.071096
7 2000-06-30 22867.0 1.627155
8 2000-06-30 15247.0 0.051387
9 2000-06-30 61574.0 1.684690
deciles = pd.qcut(df2['be/me'], 10, labels=False, duplicates = 'drop', retbins=True)
deciles
(0 5
1 1
2 3
3 7
4 4
5 2
6 6
7 8
8 0
9 9
Name: be/me, dtype: int64,
array([0.051387 , 0.0534327, 0.0687592, 0.0865165, 0.1783528, 0.444633 ,
0.8206488, 1.1524233, 1.3991806, 1.6329085, 1.68469 ]))
df.loc[:,'deciles'] = np.digitize(df['be/me'],deciles[1])-1
df
date stock_od be/me deciles
0 2000-01-31 1004.0 0.3 4
1 2000-02-29 1004.0 0.7 5
2 2000-03-31 1004.0 1.2 7
3 2000-04-30 1004.0 2.3 10
4 2000-05-31 1004.0 0.9 6
5 2020-12-31 3900.0 1.7 10
6 2020-12-31 3900.0 2.8 10
7 2020-12-31 3900.0 3.0 10
8 2020-12-31 3900.0 0.2 4
9 2020-12-31 3900.0 2.1 10
使用retbins=True
到pd.qcut()
的参数,您会得到一个元组,其中第二项是包含bin(此处为十分位)边的数组。
然后,您将非常方便的 numpy 函数 np.digitize()
(https://numpy.org/doc/stable/reference/generated/numpy.digitize.html) 应用到 df
列 be/me
,它会为每个值提供它所属的 bin(十分位)。
注意:我添加了一个 -1
,因为 numpy 函数 np.digitize()
与 pd.qcut()
传递的值相比返回下一个十分位数。可能是因为np.digitize()
分别为位于较低和较高 bin 边缘之外的值保留十分位数 0 和 10。
【讨论】:
以上是关于如何将数据框中的值分配给在另一个数据框中创建的十分位数?的主要内容,如果未能解决你的问题,请参考以下文章
如何将列表中的值分配给熊猫数据框并控制每个列表元素在数据框中的分布/频率