如何在Pandas中传入内置函数作为参数?通用空值处理函数报错求解
Got it, let's work through this issue step by step. The AttributeError: 'Series' object has no attribute 'action' happens because you're trying to call a method named action directly on the Series—but action is just a string parameter (like "mean"), not an actual built-in method of the Pandas Series object.
Here are two clean, scalable ways to properly pass and use these Pandas methods as parameters:
Method 1: Use getattr() to Dynamically Access Methods
The getattr() function lets you fetch an object's method using a string, which is exactly what we need here. We'll also handle the "delete" case separately since it's a DataFrame-level operation, not a fill operation.
import pandas as pd def fill_null(df, col_name, action): # Make a copy to avoid modifying the original DataFrame df_tmp = df.copy() target_col = df_tmp[col_name] if action in ["mean", "median"]: # Dynamically get the method (e.g., target_col.mean()) and call it fill_value = getattr(target_col, action)() df_tmp[col_name] = target_col.fillna(fill_value) elif action == "drop": # Remove rows with null values in the target column df_tmp = df_tmp.dropna(subset=[col_name]) else: raise ValueError("Invalid action. Choose from 'mean', 'median', 'drop'") return df_tmp if __name__ == '__main__': df_sal = pd.read_excel("sample_sal.xlsx") # Test mean filling df_mean_filled = fill_null(df_sal, "Salary", "mean") print("Mean-filled Salary Data:\n", df_mean_filled) # Test null row deletion df_dropped_nulls = fill_null(df_sal, "Salary", "drop") print("\nData after removing null Salary rows:\n", df_dropped_nulls)
Method 2: Use a Dictionary to Map Actions to Logic
This approach makes your code more readable and easier to extend (e.g., adding a "mode" fill later). We map each action string to a lambda function that executes the corresponding logic.
import pandas as pd def fill_null(df, col_name, action): df_tmp = df.copy() target_col = df_tmp[col_name] # Map action strings to their respective operations action_logic = { "mean": lambda: target_col.fillna(target_col.mean()), "median": lambda: target_col.fillna(target_col.median()), "drop": lambda: df_tmp.dropna(subset=[col_name]) } if action not in action_logic: raise ValueError("Invalid action. Choose from 'mean', 'median', 'drop'") result = action_logic[action]() # Handle fill vs drop operations differently if action in ["mean", "median"]: df_tmp[col_name] = result return df_tmp else: return result if __name__ == '__main__': df_sal = pd.read_excel("sample_sal.xlsx") df_median_filled = fill_null(df_sal, "Salary", "median") print("Median-filled Salary Data:\n", df_median_filled)
Key Explanation
Your original code tried to call df[col_name].action()—this treats action as a literal method name, not the string value you passed to the function. Using getattr() or a dictionary mapping lets you translate the string parameter into the actual Pandas method you want to run.
内容的提问来源于stack exchange,提问作者Sidhartha

