如何将数据框中的值分配给在另一个数据框中创建的十分位数?
How do I assign values from a dataframe to deciles created in another dataframe?
我正在使用两个数据帧:
df
包含 20 年期间(按月计算)的股票列 be/me
。
df2
,df
的一个子集(只有某些股票,仅针对 6 月)包含列 decile
,通过 pd.qcut()
方法为每年创建在 20 年期间基于 df
的 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
创建的十分位数适合原始 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,
...]
明确一点:您想知道 df
中的每个 be/me
值,如果该值在 df2
中,它会落入哪个十分位数?我看到两种情况:
如果df2
涵盖整个六月(如您所写),恐怕无法回答这个问题:该月的每一天都会有不同的等分箱边缘(因为你在 df2
上做 groupby('date')
)。 df
中的相同 be/me
值可能属于 df2
中的不同十分位数,具体取决于您考虑的 6 月的哪一天。
如果 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()
returns下个等分比什么pd.qcut()
发表。可能是因为 np.digitize()
分别为落在较低和较高 bin 边缘之外的值保留十分位数 0 和 10。
我正在使用两个数据帧:
df
包含 20 年期间(按月计算)的股票列be/me
。df2
,df
的一个子集(只有某些股票,仅针对 6 月)包含列decile
,通过pd.qcut()
方法为每年创建在 20 年期间基于df
的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
创建的十分位数适合原始 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,
...]
明确一点:您想知道 df
中的每个 be/me
值,如果该值在 df2
中,它会落入哪个十分位数?我看到两种情况:
如果
df2
涵盖整个六月(如您所写),恐怕无法回答这个问题:该月的每一天都会有不同的等分箱边缘(因为你在df2
上做groupby('date')
)。df
中的相同be/me
值可能属于df2
中的不同十分位数,具体取决于您考虑的 6 月的哪一天。如果
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()
returns下个等分比什么pd.qcut()
发表。可能是因为 np.digitize()
分别为落在较低和较高 bin 边缘之外的值保留十分位数 0 和 10。