如何将月度格式数据转换为日度格式数据的技术咨询
Got it, let's break down how to expand your monthly data to daily granularity while keeping your existing daily data intact. I'll use Python with pandas (the go-to tool for this kind of data manipulation) since it's efficient and straightforward for date-based tasks.
Step 1: Prepare Your Combined Data
First, read all your worksheet data into a single DataFrame and ensure your date column is properly parsed as datetime. This makes date operations much easier:
import pandas as pd # Assume you've already loaded all worksheet data into a list called `dfs` combined_df = pd.concat(dfs, ignore_index=True) # Convert date column to datetime (adjust column name if yours is different) combined_df['date'] = pd.to_datetime(combined_df['date']) # Set date as index for easier resampling combined_df = combined_df.set_index('date')
Step 2: Identify Monthly vs Daily Data
Monthly data will have exactly one entry per month (the last business day), while daily data has multiple entries per month. We can group by month to distinguish these:
# Add a year-month column to group by combined_df['year_month'] = combined_df.index.to_period('M')
Step 3: Expand Monthly Data to Full Month
The key here is to take each monthly entry and apply its value to every day in that month. We can use groupby and transform to handle this efficiently:
# For each month, if there's only one entry (monthly data), fill all days with that value; keep daily data as-is combined_df['value'] = combined_df.groupby('year_month')['value'].transform( lambda x: x.iloc[0] if len(x) == 1 else x )
Step 4: Resample to Daily Granularity
Now we just need to resample the data to daily frequency, filling in any gaps (which will be the days in months that had only monthly data):
# Resample to daily, forward-fill to carry the monthly value across all days final_daily_df = combined_df.resample('D').ffill().reset_index() # Optional: Drop the temporary year_month column if you don't need it final_daily_df = final_daily_df.drop('year_month', axis=1)
Handling Edge Cases
- Overlapping Data: If a month has both daily and monthly entries (unlikely in your case), the code above will prioritize the daily data since we only overwrite values for months with a single entry.
- Leap Years: Pandas handles leap days automatically when generating date ranges, so February 29 will be included correctly in leap years.
- Non-Standard Month Ends: If some monthly dates aren't the absolute last day of the month (but are the last business day), the code still works because we're grouping by the full month, not just the end date.
Alternative (More Explicit) Approach
If you prefer a more step-by-step method to see exactly what's happening, you can split the data into monthly and daily subsets, expand the monthly data, then merge:
# Split into monthly and daily data monthly_mask = combined_df.groupby('year_month')['value'].transform('count') == 1 monthly_df = combined_df[monthly_mask].copy() daily_df = combined_df[~monthly_mask].copy() # Expand monthly data to all days in the month expanded_monthly = [] for idx, row in monthly_df.iterrows(): # Get first and last day of the month month_start = idx.replace(day=1) month_end = idx # Generate all dates in the month date_range = pd.date_range(month_start, month_end, freq='D') # Create a new DataFrame with the same value for every date expanded = pd.DataFrame({'value': row['value']}, index=date_range) expanded_monthly.append(expanded) # Combine expanded monthly data with original daily data final_daily_df = pd.concat([daily_df, *expanded_monthly]).sort_index().reset_index() final_daily_df = final_daily_df.rename(columns={'index': 'date'})
Either approach will get you the result you need: every date in your dataset will have a value, with monthly data values applied to all days in their respective months.
内容的提问来源于stack exchange,提问作者DGMS89

