如何按指定列折叠Pandas DataFrame并为不同列应用不同逻辑
Great question! When you need to group a Pandas DataFrame by a specific column and apply different aggregation/folding logic to other columns (including custom complex logic), here's how you can approach it step by step:
First, let's start with your example scenario, then expand to more complex custom logic.
Step 1: Set up the sample data
First, let's recreate your sample DataFrame:
import pandas as pd data = { 'City': ['Seattle', 'Seattle', 'Portland', 'Portland'], 'ColumnA': [20, 30, 25, 10], 'ColumnB': [30, 20, 25, 40] } df = pd.DataFrame(data)
Step 2: Basic aggregation (match your expected result)
Use groupby() combined with agg(), passing a dictionary that maps each column to its desired aggregation logic. For your example, we want ColumnA to keep the minimum value and ColumnB to keep the average:
# Group by City, apply column-specific aggregation result = df.groupby('City').agg({ 'ColumnA': 'min', # Retain minimum value for ColumnA 'ColumnB': 'mean' # Retain average value for ColumnB }).reset_index() # Reset index to make City a regular column again print(result)
This outputs exactly what you're looking for:
City ColumnA ColumnB 0 Portland 10 32.5 1 Seattle 20 25.0
Step 3: Apply custom complex logic
For more advanced use cases, you can use lambda functions or custom defined functions in the aggregation dictionary.
Example 1: Single-column custom logic
Suppose you want ColumnA to take the minimum value plus 5, and ColumnB to calculate twice the standard deviation of the group:
# Define a custom function for complex logic def custom_std_logic(col): return col.std() * 2 # Mix built-in and custom functions result_custom = df.groupby('City').agg({ 'ColumnA': lambda x: x.min() + 5, # Min value +5 for ColumnA 'ColumnB': custom_std_logic # Custom std-based logic for ColumnB }).reset_index() print(result_custom)
Output:
City ColumnA ColumnB 0 Portland 15 21.213203 1 Seattle 25 14.142136
Example 2: Multi-column linked logic
If your logic requires using values from multiple columns in the group (e.g., combine ColumnA and ColumnB values), use groupby.apply() instead. This lets you work with the entire group's DataFrame:
# Custom function that uses multiple columns from the group def multi_column_logic(group): min_a = group['ColumnA'].min() mean_b = group['ColumnB'].mean() # Return a Series with the results we want to keep return pd.Series({ 'City': group.name, 'MinA_Plus_MeanB': min_a + mean_b, 'Max_ColumnA': group['ColumnA'].max() }) # Apply the function to each group result_multi = df.groupby('City').apply(multi_column_logic).reset_index(drop=True) print(result_multi)
Output:
City MinA_Plus_MeanB Max_ColumnA 0 Portland 42.5 25 1 Seattle 45.0 30
Key Notes
- Use
agg()for column-specific, independent logic (most common use case) - Use
apply()when your logic depends on multiple columns in the group - Custom functions passed to
agg()receive a Pandas Series (the column data for the group), so you can use any Series methods within them - Always use
reset_index()after grouping if you want the grouped column (likeCity) to be a regular column instead of the index
内容的提问来源于stack exchange,提问作者Didac Perez Parera

