You want to
- values from one DataFrame are replaced by the other under a certain situation
- ensure that 0 or NaN are treated equally
For (2), you can replaces 0s with NaNs, and for (1) you can use pd.Series.fillna to fill NaNs in UPOR with NPOR, but only where it is NaN.
i = GU_ES3['Qnd,hw_m2']
j = GU_ES3['UPOR'].replace(0, np.nan).fillna(GU_ES3['NPOR'])
GU_ES3['Qnd'] = i * j
Alternatively, you may use np.where to perform replacement:
GU_ES3['Qnd'] = GU_ES3['Qnd,hw_m2'] * np.where(
GU_ES3['UPOR'].replace({0 : np.nan}).isna(), GU_ES3['NPOR'], GU_ES3['UPOR']
)
Note that with replace, if, for example, you want to also replace 1, 2, or 3, you would simply need to use .replace(dict.fromkeys([1, 2, 3], np.nan)) in your code.