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

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 年期间(每月)的股票。 df2df 的子集(仅包含某些股票,仅适用于 6 月)包含 decile 列,通过 pd.qcut() 方法创建,基于 @ 的更改版本,在 20 年期间的每一年987654327@的be/me

考虑到我在df2 中创建的十分位数,我想知道是否可以根据df2decile 列对dfbe/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-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=Truepd.qcut() 的参数,您会得到一个元组,其中第二项是包含bin(此处为十分位)边的数组。 然后,您将非常方便的 numpy 函数 np.digitize() (https://numpy.org/doc/stable/reference/generated/numpy.digitize.html) 应用到 dfbe/me,它会为每个值提供它所属的 bin(十分位)。

注意:我添加了一个 -1,因为 numpy 函数 np.digitize()pd.qcut() 传递的值相比返回下一个十分位数。可能是因为np.digitize() 分别为位于较低和较高 bin 边缘之外的值保留十分位数 0 和 10。

【讨论】:

以上是关于如何将数据框中的值分配给在另一个数据框中创建的十分位数?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 pandas 数据框中的不同组分配唯一 ID?

如何将列表中的值分配给熊猫数据框并控制每个列表元素在数据框中的分布/频率

如何根据火花数据框中的值的累积总和为每一行分配一个类别?

如何限制在 VS 设计器中创建的编辑框中的数字

保留数据框中的行,对于某些列的值的所有组合,在另一列中包含相同的元素

如何将数据框中的一行的值与另一个数据框中的多行进行比较(包括计算)