def weight_mean(arr, wei, NaN=False):
    """Perform the weight mean.
    
    Parameters:
    1. arr: the array of numbers
    2. wei: the array of weights.
    
    Each number in arr is weighted by its corresponding weight in wei and added. Then divided by the total weight (sum of weight)
    
    If NaN=True, NaNs in arr are rejected in calculating the weighted mean. 
    BE CAUTIONS! if NaN=False, but there are NaNs in arr, an wanted result may come.
    """
    
    if NaN:
        sw = sum(map(lambda x, y: (x==x) and y, arr, wei))
        swa = sum(map(lambda x, y: (x==x) and x*y or 0, arr, wei))
        
        try:
            return 1.0*swa/sw
        except ZeroDivisionError:
            return float('nan')
    
    else:   # when NaNs are not considered. This is faster, but make sure that there are no NaNs in arr and wei.
        sw = sum(wei)
        swa = sum(map(lambda x, y: x * y, arr, wei))
        
        try:
            return 1.0*swa/sw
        except ZeroDivisionError:
            return 0.0