如何用一个DataFrame的qcut分位数区间对另一个DataFrame分类?
问题解决:基于分组分位数区间为DataFrame打分类标签
需求说明
需要从按PriceDate(实际数据中为Trade_Date)分组的第二个DataFrame(df2)中计算分位数区间,再用这些区间对第一个DataFrame(df1)中相同日期的价格数值进行分类,为df1添加分类标签列:
- 例如2023-10-01的区间为(-0.001, 3.2]和(3.2, 9.3],对应标签0和1
- 2023-10-02的区间为(0.699, 6.5]和(6.5, 10.0],对应标签0和1
解决方案步骤
- 生成每个日期的分位数区间:对df2按日期分组,计算每组价格的分位数边界(以2分位数为例),整理成可关联的DataFrame
- 关联区间到df1:通过日期字段将分位数区间合并到df1,确保每条记录匹配对应日期的区间
- 按日期分组应用区间分类:对合并后的DataFrame按日期分组,用
pd.cut将价格映射到对应标签
完整可运行代码
示例数据版本
import pandas as pd import numpy as np # 示例数据 df1 = pd.DataFrame({'Price':[4.4, 3.6, 9.2, 3.4], 'PriceDate':['2023-10-01', '2023-10-01','2023-10-01', '2023-10-02']}) df2 = pd.DataFrame({'Price':[0.0, 3.6, 9.3, 4.5, 2.9, 3.2, 1.0, 6.7, 8.7, 9.8, 3.4, .7, 2.2, 6.5, 3.4, 1.7, 9.4, 10.0], 'PriceDate':['2023-10-01', '2023-10-01', '2023-10-01', '2023-10-01', '2023-10-01', '2023-10-01', '2023-10-01', '2023-10-02', '2023-10-02', '2023-10-02', '2023-10-02', '2023-10-02', '2023-10-02', '2023-10-02', '2023-10-02', '2023-10-02', '2023-10-02', '2023-10-02']}) # 生成每个日期的分位数区间 bins_df = df2.groupby('PriceDate')['Price'].apply(lambda x: pd.qcut(x, q=2, retbins=True)[1]).reset_index(name='Bins') # 合并区间到df1 merged_df = pd.merge(df1, bins_df, on='PriceDate', how='left') # 定义分类函数 def assign_rank(group): bins = group['Bins'].iloc[0] # 扩展区间边界,处理超出原区间的数值 extended_bins = [-np.inf] + bins[1:-1].tolist() + [np.inf] return pd.cut(group['Price'], bins=extended_bins, labels=False) # 按日期分组应用分类 merged_df['Rank'] = merged_df.groupby('PriceDate', group_keys=False).apply(assign_rank) # 查看结果 print(merged_df)
实际数据版本
import pandas as pd import numpy as np # 读取实际数据 df1 = pd.read_csv("c:/temp/subsetfills.csv", index_col=False) df2 = pd.read_csv("c:/temp/allfills.csv", index_col=False) # 生成每个Trade_Date的分位数区间(2分位数) bins_df = df2.groupby('Trade_Date')['ExecPrice'].apply(lambda x: pd.qcut(x, q=2, retbins=True)[1]).reset_index(name='Bins') # 合并区间到df1 merged_df = pd.merge(df1, bins_df, on='Trade_Date', how='left') # 定义分类函数 def assign_rank(group): bins = group['Bins'].iloc[0] # 扩展区间边界,处理超出原区间的数值 extended_bins = [-np.inf] + bins[1:-1].tolist() + [np.inf] return pd.cut(group['Price'], bins=extended_bins, labels=False) # 按Trade_Date分组应用分类,生成GroupPrice merged_df['GroupPrice'] = merged_df.groupby('Trade_Date', group_keys=False).apply(assign_rank) # 查看结果 print(merged_df)
关键修正点
你之前的代码错误地使用ExecPrice作为分组键,应改为按日期字段(Trade_Date)分组,确保每个日期的区间被正确应用到对应记录。
内容的提问来源于stack exchange,提问作者Stumbling Through Data Science
相关产品推荐
相关产品推荐

