Why avoid looping over DataFrame rows?
beginnerAnswer
pandas operations are vectorised — they apply to a whole column in compiled code rather than one row at a time in Python. The difference is commonly around a hundredfold.
df['total'] = df['price'] * df['qty'] replaces a loop, and reads better.
For conditional logic, np.where covers two outcomes and np.select covers several. apply is the fallback for logic that genuinely cannot be vectorised, but it still runs per row, so it is not a performance solution.
Loops remain appropriate for things that are not columns of data — iterating over files, or over a list of report parameters.