如何遍历DataFrame列执行计算,并优化matplotlib绘图中的重复列计算?
Hey there! Let's break down your two pandas and matplotlib questions with practical, optimized solutions:
There are a few flexible ways to do this, depending on how complex your calculations are:
Directly iterate over column names (great for custom/complex logic)
You can loop throughdf.columnsand access each column individually to run your calculations. For example, if you want to compute the range (max - min) for every column:import pandas as pd df = pd.DataFrame({'A': [1,2,3], 'B': [4,5,6], 'C': [7,8,9]}) for col in df.columns: col_range = df[col].max() - df[col].min() print(f"Range of {col}: {col_range}")Use
df.apply()(cleaner for vectorized calculations)
For simpler, vectorized operations,apply()lets you run a function across all columns (useaxis=0for columns). Here's the same range calculation withapply:column_ranges = df.apply(lambda x: x.max() - x.min(), axis=0) print(column_ranges)Use
df.items()(iterate over column-name and column-data pairs)
If you need both the column name and its data in one go,items()(formerlyiteritems()) is handy:for col_name, col_data in df.items(): mean_val = col_data.mean() print(f"Mean of {col_name}: {mean_val}")
Your current code repeats df.groupby(['PAPERLESS']) multiple times, which is inefficient—each call re-computes the grouping, wasting time (especially with large datasets). Here's how to fix this and clean up your plotting logic:
Step 1: Do the Groupby ONCE, then reuse the grouped object
First, create a single grouped object, then extract the aggregations you need from it:
import matplotlib.pyplot as plt %matplotlib inline # First, create the grouped object once grouped = df.groupby(['PAPERLESS']) # Now extract your aggregations from the pre-computed group account_counts = grouped['ACCOUNT'].count().rename('ACCOUNT') case_sums = grouped['cases'].sum().rename('cases') # Add any other aggregations you need here, e.g.: # total_amount = grouped['amount'].sum().rename('total_amount')
Step 2: Even better—use agg() to get all aggregations in one DataFrame
If you have multiple columns to aggregate, agg() lets you define all calculations in one step, returning a clean DataFrame you can use directly for plotting:
# Define a dictionary mapping columns to their aggregation functions agg_dict = { 'ACCOUNT': 'count', 'cases': 'sum', # Add more columns and functions here, e.g. 'amount': 'mean' } # Get all aggregations in a single DataFrame agg_results = grouped.agg(agg_dict)
Step 3: Dynamically plot all columns (no more hardcoding ax1, ax2, ax3!)
Instead of manually defining ax1, ax2, ax3, create subplots dynamically based on the number of columns in your aggregated results. This makes your code scalable if you add more columns later:
# Create subplots: 1 row, number of columns = number of aggregated metrics fig, axes = plt.subplots(nrows=1, ncols=len(agg_results.columns), sharex=False, sharey=True, figsize=(15,5)) # Loop through each axis and column to plot for ax, col in zip(axes, agg_results.columns): agg_results[col].plot(kind='bar', ax=ax, title=f'{col} by Paperless Status') ax.set_xlabel('Paperless') ax.set_ylabel(col) plt.tight_layout() # Adjust spacing between plots plt.show()
This approach cuts down on redundant computation, makes your code easier to maintain, and scales seamlessly if you need to add more metrics later.
内容的提问来源于stack exchange,提问作者marmar

