如何在不使用.apply/.transform/.agg的前提下,基于Pandas多Groupby计算每日C/P成交量比率
Since your initial groupby gives you a multi-index Series of summed volumes per date and cp_flag, we can leverage unstacking to reshape the data into a format where we can directly compute the ratio—no need for apply/transform/agg methods.
Step-by-Step Breakdown:
Get Grouped Volume Sums
First, run your existing groupby code to get the total volume per date and cp_flag:grouped_volume = df.groupby(['date', 'cp_flag']).volume.sum()This gives you a Series with a multi-index (
date,cp_flag) and summed volume values, like:date cp_flag 2015-01-02 C 170381 P 366072 2015-01-03 C 220500 P 580000 ... Name: volume, dtype: int64Unstack to Reshape Data
Useunstack()to pivot thecp_flagindex level into columns. This turns your multi-index Series into a DataFrame where each row is a date, and columns areCandPwith their respective total volumes:daily_cp_volumes = grouped_volume.unstack('cp_flag')Resulting DataFrame:
cp_flag C P date 2015-01-02 170381 366072 2015-01-03 220500 580000 ...Compute C/P Ratio
Now you can simply divide theCcolumn by thePcolumn to get your desired daily ratio as a Series:cp_ratio = daily_cp_volumes['C'] / daily_cp_volumes['P']The output will be exactly what you want:
date 2015-01-02 0.465 2015-01-03 0.380 ... 2020-12-31 0.309 dtype: float64
Full Combined Code:
# Calculate grouped volume sums grouped_volume = df.groupby(['date', 'cp_flag']).volume.sum() # Reshape and compute ratio daily_cp = grouped_volume.unstack('cp_flag') cp_ratio = daily_cp['C'] / daily_cp['P']
Edge Case Note:
If some dates are missing either C or P entries, the corresponding ratio will be NaN. If you want to handle this (e.g., fill with 0 or drop those dates), you can use dropna() or fillna() on the final cp_ratio Series:
# Drop dates with missing C/P values cp_ratio_clean = cp_ratio.dropna() # Or fill missing ratios with 0 cp_ratio_filled = cp_ratio.fillna(0)
内容的提问来源于stack exchange,提问作者des224

