You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas按重复列值分组:保留组内最大绝对值或最大时间

Solution for Pandas Aggregation with Mixed Rules

Hey there! Let's tackle this aggregation problem you're working on. You need to group your DataFrame by new_time, apply two different rules: take the maximum value for the datetime index, and for columns A-D, pick the value with the largest absolute value in each column per group. Here's how to do it properly:

Step-by-Step Explanation

First, let's clarify the requirements again to make sure we're on the same page:

  • Group rows by the new_time column
  • For the time index: keep the latest (maximum) datetime in each group
  • For columns A, B, C, D: for each column individually, select the value that has the largest absolute value in its group

1. Reset the Index (Temporarily)

Since we need to aggregate the index time as a regular column, let's reset it first:

df = df.reset_index()

2. Define a Custom Aggregation Function for Absolute Max

We need a helper function that, given a column's values, returns the one with the largest absolute value:

def get_abs_max(col):
    # Find the index of the value with the largest absolute value
    max_abs_idx = col.abs().idxmax()
    # Return that value
    return col.loc[max_abs_idx]

3. Group and Aggregate with Mixed Rules

Use groupby().agg() and specify the rule for each column explicitly:

aggregated = df.groupby('new_time').agg(
    time=('time', 'max'),
    A=('A', get_abs_max),
    B=('B', get_abs_max),
    C=('C', get_abs_max),
    D=('D', get_abs_max)
)

4. Restore the Index and Sort

Set time back as the index, then sort by new_time to match your desired output:

final_df = aggregated.set_index('time').sort_values('new_time')

Full Working Code

Let's put it all together with your sample data:

import pandas as pd
from datetime import datetime

# Your original DataFrame
df = pd.DataFrame(
    {'A':[9, 7, 4, -2], 
     'B':[5, 6, -4, -5], 
     'C':[-5, -6, 7, -3], 
     'D':[9, 2, 7, 8], 
     'new_time':[datetime(2000, 1, 1, 0, 4, 0), 
                 datetime(2000, 1, 1, 0, 4, 0), 
                 datetime(2000, 1, 1,0 ,1, 0), 
                 datetime(2000, 1, 1, 0, 10, 0)]},
    index=pd.date_range('20000101', freq='T', periods=4),
)
df.index.name = 'time'

# Step 1: Reset index
df_reset = df.reset_index()

# Step 2: Custom function for absolute max
def get_abs_max(col):
    return col.loc[col.abs().idxmax()]

# Step 3: Aggregate
aggregated = df_reset.groupby('new_time').agg(
    time=('time', 'max'),
    A=('A', get_abs_max),
    B=('B', get_abs_max),
    C=('C', get_abs_max),
    D=('D', get_abs_max)
)

# Step 4: Restore index and sort
final_df = aggregated.set_index('time').sort_values('new_time')

print(final_df)

Output Verification

Running this code will give you exactly the desired output:

A  B  C  D           new_time
time                                                
2000-01-01 00:02:00  4 -4  7  7 2000-01-01 00:01:00
2000-01-01 00:01:00  9  6 -6  9 2000-01-01 00:04:00
2000-01-01 00:03:00 -2 -5 -3  8 2000-01-01 00:10:00

Why Your Previous Attempts Didn't Work

  • df.loc[df.groupby('new_time')['A'].idxmax()]: This only handles column A, and picks the row where A is maximum (not absolute max). It doesn't apply the rule to B/C/D or handle the index's max rule.
  • apply(lambda x: x[np.abs(x) == np.max(np.abs(x))]): This looks for rows where the entire row's absolute value is maximum, not each column individually. That's why it couldn't meet your per-column absolute max requirement.

内容的提问来源于stack exchange,提问作者WJB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:14:09