How can I develop a 0-100 composite or index score using multiple Z scores from multiple independent variables? I'm really interested in index scores like the human development index or economic freedom index where they rank things on a 0-100 scale based off of a bunch of different variables (e.g. press freedom, property rights, etc). I would like to do this with z-scores for multiple columns in a Python notebook.
I'm able to calculate the Z scores just fine using scipy:
from scipy.stats import zscore
no_income_data_important_columns_only.apply(zscore)

and get something like: I understand these z-scores are telling me how high or low the values are relative to the average. But now I want to be able to understand how high or low each row is across all of the measurements/columns...
I don't really know what to do with all the Z-scores in order to calculate an index or composite score (on a 0 to 100 scale). Do I multiply them or add them together or do something else to aggregate them?
 A: Suppose you have a composite z-score that is roughly normal with mean approximately 0 and standard deviation approximately 1. Then transforming with the standard normal CDF $\Phi$ (pnorm in R) will give you scores that are approximately uniformly distributed on $(0,1).$ Multiplying by 100 will give you 'index' scores between $0$ and $100.$
Here is an example in R, beginning with z-scores for 250 simulated items.
set.seed(2020)
z = rnorm(250)  # population mean 0 and SD 1 are the default
summary(z);  length(z);  sd(z)
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-3.056684 -0.739665  0.067159  0.006864  0.710861  3.201632 
[1] 250
[1] 1.120193
u = pnorm(z)    # approx uniformly distributed on (0,1)
summary(u)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.001119 0.229755 0.526771 0.504363 0.761384 0.999317 
x = 100*u       # proposed index scores
summary(x);  sd(x)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.1119 22.9755 52.6771 50.4363 76.1384 99.9317 
[1] 30.30388

par(mfrow=c(1,2))
 hist(z, prob=T, col="skyblue2", main="Z Scores"); rug(z)
 hist(x, prob=T, col="skyblue2", main="Index Scores"); rug(x)
par(mfrow=c(1,1))


