如何将数据框中的值分配给在另一个数据框中创建的十分位数?

How do I assign values from a dataframe to deciles created in another dataframe?

我正在使用两个数据帧:

考虑到我在 df2 中创建的十分位数,我想知道是否可以根据 df2deciledfbe/me 进行排名] 柱子。换句话说,我想知道是否可以将 dfbe/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 中,它会落入哪个十分位数?我看到两种情况:

  1. 如果df2涵盖整个六月(如您所写),恐怕无法回答这个问题:该月的每一天都会有不同的等分箱边缘(因为你在 df2 上做 groupby('date'))。 df 中的相同 be/me 值可能属于 df2 中的不同十分位数,具体取决于您考虑的 6 月的哪一天。

  2. 如果 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=Truepd.qcut() 的参数,您将得到一个元组,其中第二项是包含 bin(此处为十分位数)边的数组。 然后,您将非常方便的 numpy 函数 np.digitize() (https://numpy.org/doc/stable/reference/generated/numpy.digitize.html) 应用到 dfbe/me,它为每个值提供它所属的 bin(十分位数)。

注:我加了一个-1因为numpy的函数np.digitize()returns下个等分比什么pd.qcut()发表。可能是因为 np.digitize() 分别为落在较低和较高 bin 边缘之外的值保留十分位数 0 和 10。