关于fillna基于前后行填充DataFrame空值及行数限制的技术问询
Great question! Let's break this down step by step:
1. Does fillna support filling NaNs surrounded by the same non-null value?
Short answer: No, fillna doesn't have a built-in parameter for this exact logic. But you can easily achieve it by combining pandas' ffill() (forward fill) and bfill() (backward fill) methods with a conditional check.
Here's how to implement your desired result:
First, let's recreate your sample DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame({ 'values': ['str1', 'str1', np.nan, np.nan, 'str1', np.nan, np.nan, 'str2', np.nan, np.nan, 'str2'] })
Next, we'll generate forward-filled and backward-filled versions of the column, then only fill NaNs where both fills produce the same value (meaning the NaN is surrounded by identical non-null values):
# Generate forward and backward filled series forward_filled = df['values'].ffill() backward_filled = df['values'].bfill() # Fill NaNs only where both fills match (surrounded by same value) df['filled_values'] = np.where( df['values'].isna() & (forward_filled == backward_filled), forward_filled, df['values'] )
The resulting filled_values column will be exactly what you want:['str1', 'str1', 'str1', 'str1', 'str1', nan, nan, 'str2', 'str2', 'str2', 'str2']
2. Can we set a limit on the number of rows to fill between two str_i values?
Absolutely! You can use the limit parameter in ffill() and bfill() to control the maximum number of consecutive NaNs to fill from either direction. This translates to limiting how many rows between two matching non-null values get filled.
For example, if you have 3 consecutive NaNs between two str1 values and only want to fill the first 2:
# Sample DataFrame with 3 NaNs between str1s df_limit = pd.DataFrame({ 'values': ['str1', np.nan, np.nan, np.nan, 'str1'] }) # Apply fill with limit of 2 forward_filled_limit = df_limit['values'].ffill(limit=2) backward_filled_limit = df_limit['values'].bfill(limit=2) df_limit['filled_values'] = np.where( df_limit['values'].isna() & (forward_filled_limit == backward_filled_limit), forward_filled_limit, df_limit['values'] )
The result here will be ['str1', 'str1', 'str1', nan, 'str1'] — only the first 2 NaNs get filled, since the third one isn't covered by both the forward and backward fill with a limit of 2.
内容的提问来源于stack exchange,提问作者Pi-R

