如何使用Pandas按连续天数分组拆分DataFrame?
Great question! Let's break down how to group your DataFrame by consecutive blocks of days (whether it's 2 days, 4 days, or any custom interval) in Pandas. Here are two straightforward approaches depending on your needs:
1. Fixed Consecutive Day Groups (e.g., Every 2 Days)
If you want to split days into equal-sized consecutive blocks (like every 2 days, every 4 days), the simplest way is to generate a group ID using integer division. This works regardless of how many rows each day has.
Step-by-Step Code:
import pandas as pd # Your original data setup df = pd.DataFrame({ 'day' : [1,1,2,3,3,3,4,4], 'user' : ['A','A','B','C','B','B','C','C'], 'score': [10,5,5,10,5,5,0,5] }) df["total"] = df.cumsum()["score"] # Define your group size (e.g., 2 days per group, change to 4 for larger blocks) days_per_group = 2 # Calculate group ID for each row # (day - 1) ensures we start grouping from day 1 as the first block df['group_id'] = (df['day'] - 1) // days_per_group # Now you can group by this ID to get your desired blocks for group_num, group_data in df.groupby('group_id'): start_day = group_num * days_per_group + 1 end_day = (group_num + 1) * days_per_group print(f"=== Group {group_num + 1} (Days {start_day} to {end_day}) ===") print(group_data) print("\n")
How It Works:
The expression (df['day'] - 1) // days_per_group maps consecutive days to the same group ID:
- For
days_per_group=2: Day 1 & 2 → ID 0; Day 3 & 4 → ID 1 - For
days_per_group=4: Days 1-4 → ID 0, and so on
If your days don't start at 1 (e.g., starting at day 5), adjust the formula to (df['day'] - df['day'].min()) // days_per_group to maintain consecutive blocks relative to your first day.
2. Custom Day Interval Groups (Arbitrary Ranges)
If you need non-uniform groups (like 1-3 days in one group, 4-6 in another), use pd.cut() to define custom day boundaries.
Step-by-Step Code:
# Define custom day bins (adjust these to your needs) # Bins are [lower bound, upper bound), right=False makes intervals left-closed day_bins = [0, 2, 4, float('inf')] group_labels = ['Group 1 (Days 1-2)', 'Group 2 (Days 3-4)', 'Group 3+'] # Assign groups to each row df['custom_group'] = pd.cut(df['day'], bins=day_bins, labels=group_labels, right=False) # View grouped results print(df.groupby('custom_group').apply(lambda x: x))
How It Works:
pd.cut()splits thedaycolumn into the intervals you define. Settingright=Falseensures intervals are left-closed (e.g.,0 < day ≤ 2captures days 1 and 2).- You can tweak
day_binsandgroup_labelsto match any custom grouping logic you need.
内容的提问来源于stack exchange,提问作者Shlomi Schwartz

