3D metrics for segmentation evaluation I am new to programming and I am trying to develop a machine learning approach for image segmentation (https://en.wikipedia.org/wiki/Image_segmentation) and here I want to evaluate the predicted (output) segmentation. In order to do this, I am using multiple (common) metrics (dice score, jacquard index, surface distance Hausdorff distance, diameter error and volume error). 

The code works, but it really looks bad! I heard that one of the best practices is to avoid repetition in the code. For my piece I have to create multiple arrays which will all have different usage, but generating a lot of repetitions, and I am sure there might be better way to get better performance for this piece of code. 

Do you have an idea of how to optimize this for speed and readability?

The details of the code:

folder = glab() : gets the name of the different folders containing the arrays that I want to open (glab() = glob() with natural sorting)

prediction/ground_truth : loads the predicted segmentation and ground_truth to be compared

scores() : calculates the different metrics (dice score, jacquard index, sensibility and specificity) between the ground truth and prediction

surfd() : calculates the surface distance between ground truth and prediction

diam_vol : calculates the diameter/volume and error between ground truth and prediction

Since I am evaluating multiple cases I want to know the mean() metrics to assess my model that's why I call for np.mean() for all the values at the end.

def metrics(savedir):

    """3D metrics for segmentation evaluation:

    dice score : https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient
    jacquard index : https://en.wikipedia.org/wiki/Jaccard_index
    sensibility &amp; specificity : https://en.wikipedia.org/wiki/Sensitivity_and_specificity
    diameter and volume error
    Surface distance : https://www.cs.ox.ac.uk/files/7732/CS-RR-15-08.pdf
    Hausdorff distance : https://en.wikipedia.org/wiki/Hausdorff_distance
    """

    folder = glab(savedir+"/OutputData/*/")

    # array initialization
    np_dice = np.zeros([len(folder)])
    np_jacq = np.zeros([len(folder)])
    np_sens = np.zeros([len(folder)])
    np_spec = np.zeros([len(folder)])
    np_surf = np.zeros([len(folder)])
    np_haus = np.zeros([len(folder)])

    np_diam_GT = np.zeros([len(folder)])
    np_diam_pred = np.zeros([len(folder)])
    np_diam_err = np.zeros([len(folder)])

    np_vol_GT = np.zeros([len(folder)])
    np_vol_pred = np.zeros([len(folder)])
    np_vol_err = np.zeros([len(folder)])


    for number, folder_name in enumerate(folder):

        prediction = np.load(folder_name+"prediction.npy")
        ground_truth = np.load(folder_name+"test_label.npy")

        scores = scoring(ground_truth, prediction)
        surface_distance = surfd(prediction, ground_truth, [0.625, 0.625, 0.625], 1)
        diam_vol = diam(prediction, ground_truth)

        np_dice[number] = scores[0]
        np_jacq[number] = scores[1]
        np_sens[number] = scores[2]
        np_spec[number] = scores[3]
        np_surf[number] = surface_distance.mean()
        np_haus[number] = surface_distance.max()

        np_diam_GT[number] = diam_vol[0]
        np_diam_pred[number] = diam_vol[1]
        np_diam_err[number] = diam_vol[2]

        np_vol_GT[number] = diam_vol[3]
        np_vol_pred[number] = diam_vol[4]
        np_vol_err[number] = diam_vol[5]

    mean_dice = np.mean(np_dice)
    mean_jacq = np.mean(np_jacq)
    mean_sens = np.mean(np_sens)
    mean_spec = np.mean(np_spec)
    mean_surf = np.mean(np_surf)
    mean_haus = np.mean(np_haus)
    mean_diam_GT = np.mean(np_diam_GT)
    mean_diam_pred = np.mean(np_diam_pred)
    mean_diam_err = np.mean(np_diam_err)
    mean_vol_GT = np.mean(np_vol_GT)
    mean_vol_pred = np.mean(np_vol_pred)
    mean_vol_err = np.mean(np_vol_err)

    return ([mean_dice, mean_jacq, mean_sens, mean_spec, mean_surf, mean_haus, mean_diam_GT, mean_diam_pred, mean_diam_err, mean_vol_GT, mean_vol_pred, mean_vol_err])
Realy, dud its childish!

only ones:

lenf = len(folder)


just one 2d array:

len_types = 12
arr = np.zeros([lenf ,  12])


learn how to work with numpy arrays, you will avoid the loop as well. And for example the mean can be done in one line for 2d array:

means = np.mean(arr, axis = 1)


https://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html