Pandas中where函数未返回单元格值问题求助
VT_Final Column in Pandas Let's break down why your VT_Final column is returning blank values and how to fix it step by step:
Key Issues in Your Current Code
First, let's spot the critical mistakes causing the unexpected results:
where()doesn’t modify data in-place by default: Every time you callBookings['VT_Final'].where(...), you’re creating a new Series but never assigning it back toVT_Final. Those operations effectively do nothing to your DataFrame.- Sequential overwrites erase previous work: You repeatedly assign
VT_Finaldirectly (first toV_Team1, thenV_Team2, then'Non PA'), which wipes out all prior values before yourwhere()checks can take effect. - Empty string vs. NaN mismatch: When
map()can’t find a matchingMarker1in your reference DataFrames, it returnsNaN(not an empty string''). Your checks for==''won’t catch these missing values, leading to unintended blanks.
Troubleshooting Steps
Here’s how to diagnose and fix each part:
1. Verify Your map() Results First
Before fixing the VT_Final logic, confirm that V_Team1 and V_Team2 are populated correctly:
- Run these checks to validate mapping:
# Count missing values (NaN = no match found in reference DataFrames) print("Missing V_Team1 entries:", Bookings['V_Team1'].isna().sum()) print("Missing V_Team2 entries:", Bookings['V_Team2'].isna().sum()) # Inspect sample rows to verify mapped values print(Bookings[['Marker1', 'V_Team1', 'V_Team2']].head(10)) - If you see lots of
NaNs, double-check thatMarker1values inBookingsexactly match those inManpower_1andAttrition_1(case sensitivity, extra spaces, or typos are common culprits).
2. Fix the VT_Final Logic with Proper where() Usage
Instead of overwriting and calling where() without assignment, use a chained approach that prioritizes values correctly. Here are two clean implementations:
Option 1: Chained where() for Concise Logic
# Keep your existing mapping code for V_Team1 and V_Team2 Bookings['V_Team1'] = Bookings.Marker1.map(Manpower_1.set_index('Marker1')['Vertical Team'].to_dict()) Bookings['V_Team2'] = Bookings.Marker1.map(Attrition_1.set_index('Marker1')['Vertical Team'].to_dict()) # Build VT_Final with priority: V_Team1 > V_Team2 > Non-PA Bookings['VT_Final'] = Bookings['V_Team1'].where( Bookings['V_Team1'].notna(), # Use V_Team1 if it's not missing Bookings['V_Team2'].where( Bookings['V_Team2'].notna(), # Else use V_Team2 if it's not missing 'Non-PA' # Fallback to Non-PA if both are missing ) )
Option 2: numpy.where for Flatter Readability
If you prefer a more linear structure, numpy.where works great for conditional assignments:
import numpy as np Bookings['VT_Final'] = np.where( Bookings['V_Team1'].notna(), Bookings['V_Team1'], np.where( Bookings['V_Team2'].notna(), Bookings['V_Team2'], 'Non-PA' ) )
3. Handle Empty Strings (If Applicable)
If your reference DataFrames might contain actual empty strings (not just missing values), adjust checks to cover both cases:
# Check for neither NaN nor empty string has_v_team1 = Bookings['V_Team1'].notna() & (Bookings['V_Team1'] != '') has_v_team2 = Bookings['V_Team2'].notna() & (Bookings['V_Team2'] != '') Bookings['VT_Final'] = np.where( has_v_team1, Bookings['V_Team1'], np.where( has_v_team2, Bookings['V_Team2'], 'Non-PA' ) )
Final Notes
- Always remember: Pandas methods like
where(),fillna(), anddrop()return a new object by default. To modify your original DataFrame, either assign the result back or useinplace=True(thoughinplace=Trueis generally discouraged for readability). - Use
notna()instead of checking for empty strings when dealing with missing values frommap()or similar operations, as they returnNaNfor unmatched entries.
内容的提问来源于stack exchange,提问作者Vishnu Varma

