Multiple Pandas Ranking Operations within a Loop - Better Optimization and Performance
A basic principle of performance optimization in pandas is to avoid for-loops and vectorize as much computation as possible.
Here is one version of improved code:
order_df = df.rank(axis=1, method=&quot;first&quot;, na_option=&quot;bottom&quot;)
order_df_avg = df.rank(axis=1, method=&quot;average&quot;, na_option=&quot;bottom&quot;)
order_df.where(df.astype(bool), order_df_avg, inplace=True)
matrix_computed = norm.ppf(order_df / (len(df.columns) + 1))
df[:] = matrix_computed

One potential further improvement is to compute only the orders that need to be updated rather than order_df_avg.
order_df = df.rank(axis=1, method=&quot;first&quot;, na_option=&quot;bottom&quot;)
mask = (df == 0)
orders_to_update = np.broadcast_to(np.expand_dims(order_df[mask].mean(axis = 1), 1), df.shape)
order_df.mask(mask, orders_to_update, inplace=True)
matrix_computed = norm.ppf(order_df / (len(df.columns) + 1))
df[:] = matrix_computed