基于跨月日期拆分Pandas DataFrame为两个子DataFrame的需求
Hey Dave, let's tackle this problem cleanly. Your approach using .shift() was on the right track—we just need to tweak it to pinpoint the exact split point between the two months, then slice the DataFrame accordingly.
Step 1: Set Up the Example DataFrame
First, let's replicate your original data to test our solution:
import pandas as pd # Your original list of days days = [19,20,21,22,23,24,25,26,27,28,29,30,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] timesheet_df = pd.DataFrame({'Days': days})
Step 2: Identify the Split Point
The key insight is that the transition from the current month to the next will always be a drop in the Days value (e.g., 30 → 1). We can use .shift() to detect this drop and find the index where it happens:
# Find the first index where a day is smaller than the previous day (start of next month) split_index = (timesheet_df['Days'].shift() > timesheet_df['Days']).idxmax()
.shift()moves theDayscolumn down by one row, so we compare each day to the one before it.idxmax()returns the first occurrence ofTrue(the first day of the next month), which is our split point.
Step 3: Split the DataFrame
Now we can slice the original DataFrame at the split index and reset the indexes to match your desired output:
# First DataFrame: Current month (19th to end of month) df1 = timesheet_df.loc[:split_index - 1, 'Days'].reset_index(drop=True) # Second DataFrame: Next month (1st to 19th) df2 = timesheet_df.loc[split_index:, 'Days'].reset_index(drop=True)
Step 4: Verify the Results
Printing the results will match your expected output:
print("df - Number 1") print(df1) # Output: # 0 19 # 1 20 # ... # 11 30 print("\ndf - Number 2") print(df2) # Output: # 0 1 # 1 2 # ... # 18 19
Bonus: No Extra Columns Needed
The solution above avoids creating a temporary column (like your match column) for a more concise workflow. It works for any month length (30, 31, 28/29 days) as long as your days are ordered consecutively.
内容的提问来源于stack exchange,提问作者Dave Stark

