Pandas分组聚合:按Company ID分组后获取最高Post Valuation及对应Deal Date实现方案
问题:按公司ID分组获取最高Post Valuation及对应Deal Date
我手里有一张包含三列核心数据的表格,列名分别是Company ID、Post Valuation、Deal Date。现在想要实现的需求是:先按Company ID对数据进行分组,然后获取每个公司ID对应的最高Post Valuation,同时拿到这个最高估值对应的Deal Date。
我尝试过下面这段代码:
df_X.sort_values('Post Valuation', ascending=True).groupby('Company ID', as_index=False)['Post Valuation'].first()
但运行后只能拿到最高估值,没法获取对应的Deal Date,想问问该怎么修改代码才能实现想要的效果?
附表格数据:
| Company ID | Post Valuation | Deal Date |
|---|---|---|
| 60 | NaN | 2022-03-01 |
| 80 | 6.77 | 2022-02-10 |
| 85 | NaN | 2022-02-01 |
| 89 | 1.40 | 2022-01-27 |
| 104 | 6.16 | 2022-01-05 |
| 107 | 17.26 | 2022-01-03 |
| 111 | NaN | 2022-01-01 |
| 113 | NaN | 2021-12-31 |
| 119 | NaN | 2021-12-15 |
| 128 | 2.82 | 2021-12-01 |
| 130 | NaN | 2021-11-25 |
| 131 | 658.36 | 2021-11-25 |
| 150 | NaN | 2021-10-20 |
| 156 | 21.75 | 2021-10-07 |
| 170 | NaN | 2021-09-13 |
| 182 | NaN | 2021-09-01 |
| 185 | NaN | 2021-08-31 |
| 186 | NaN | 2021-08-30 |
| 191 | 8.02 | 2021-08-13 |
| 192 | NaN | 2021-08-12 |
解决方案
你原来的代码问题出在最后只选取了Post Valuation列来执行first()操作,所以自然拿不到对应的Deal Date。另外还有个小细节:你用了ascending=True是升序排序,这样取first()拿到的其实是每组里最小的估值,得改成降序才能拿到最高的!下面给你几种可行的修改方案:
方案1:调整原逻辑,保留需要的列
顺着你原来的排序+分组思路,只需要把分组时选取的列改成['Post Valuation', 'Deal Date'],同时修正排序方向:
# 先按Post Valuation降序排序,把NaN放到最后 df_sorted = df_X.sort_values('Post Valuation', ascending=False, na_position='last') # 分组后取每组第一行,就能同时拿到最高估值和对应日期 result = df_sorted.groupby('Company ID', as_index=False)[['Post Valuation', 'Deal Date']].first()
方案2:用idxmax()精准定位最高估值行
这种方法更直接,先找到每个组内Post Valuation最大的行的索引,再用索引提取整行数据:
# 获取每个组内Post Valuation最大的行的索引 idx = df_X.groupby('Company ID')['Post Valuation'].idxmax() # 根据索引提取对应行的数据,重置索引让结果更规整 result = df_X.loc[idx, ['Company ID', 'Post Valuation', 'Deal Date']].reset_index(drop=True)
小贴士:如果某个组的Post Valuation全是NaN,idxmax()会返回该组的第一个行索引,对应的Deal Date就是该组第一条记录的日期,和方案1的结果保持一致。
方案3:自定义聚合函数实现需求
如果需要更灵活的逻辑,可以用agg()配合自定义函数来同时提取目标值:
import pandas as pd def get_max_val_and_date(group): # 找到组内Post Valuation最大的行 max_row = group.loc[group['Post Valuation'].idxmax()] # 返回需要的两个值 return pd.Series([max_row['Post Valuation'], max_row['Deal Date']], index=['Post Valuation', 'Deal Date']) # 分组应用自定义函数 result = df_X.groupby('Company ID', as_index=False).apply(get_max_val_and_date).reset_index()
内容的提问来源于stack exchange,提问作者le Minh Nguyen
相关产品推荐
相关产品推荐

