2017-06-17 166 views
0

单调性百分比是数组按升序或降序排序的方式。 我需要一个Python实现这一考虑下面的例子PYTHON:numpy 2D数组排序级别的百分比

array([[2,3,4,6,5] # 60% sorted 
     [1,2,3,4,5] # 100% sorted 
     [0,2,4,8,10]# 100% sorted 
     [0,2,4,8,10]]# 100% sorted 
     /| | \ \ 
     / | | \ \ 
    100% 100% 80% 80% 100% 

Monotonicity percentage is average(80,100,100,100,100,100,80,80,100) 

我想在人工智能启发式运行此,速度是非常重要的(最好是numpy的)的方式,感谢您的帮助

EDITED 这是我有什么,现在它只是返回一个布尔值,它是一维

def mncity(arr): 
    dx = np.diff(arr) 
    return np.all(dx <= 0) or np.all(dx >= 0) 

我是新来的蟒蛇一般

+3

对不起,但这不是一个编码服务。你试过什么了?你在哪里挣扎? –

+0

谢谢你@ImanolLuengo –

回答

3

你可以使用zip()list comprehension做这样的事情:

def get_pourcent(a, order='ascending'): 
    if order == 'ascending': 
     # Check if every element is inferior than his next in the list 
     b = [1 if j < v else 0 for j, v in zip(a, a[1:])] 
     # Get how much zeros in b 
     zeros = len(b) - sum(b) 
     percent = (1 - (float(zeros)/len(a)))*100 

    elif order == 'descending': 
     b = [1 if j > v else 0 for j, v in zip(a, a[1:])] 
     zeros = sum(b) 
     percent = (float(zeros)/len(a))*100 

    else: 
     return None 

    return '"%s": %.2f%% sorted' % (order, percent) 


# Test 
tests = [('ascending', [2,3,4,6,5]), ('ascending', [1,2,3,4,5]), 
('ascending', [0,2,4,8,10]), ('descending', [2,3,4,6,5]), ('descending', [0,2,4,8,10])] 

for k, v in tests: 
    print v, get_pourcent(v, order=k) 

输出:

[2, 3, 4, 6, 5] "ascending": 80.00% sorted 
[1, 2, 3, 4, 5] "ascending": 100.00% sorted 
[0, 2, 4, 8, 10] "ascending": 100.00% sorted 
[2, 3, 4, 6, 5] "descending": 20.00% sorted 
[0, 2, 4, 8, 10] "descending": 0.00% sorted 

编辑:

tests = [[ 2, 4, 0, 8], [ 4, 24, 0, 16], [ 16, 2, 16, 32], [ 16, 2, 16, 128]] 

for k in tests: 
    print get_pourcent(k) 

将输出:

"ascending": 75.00% sorted 
"ascending": 75.00% sorted 
"ascending": 75.00% sorted 
"ascending": 75.00% sorted 
+1

我喜欢这个解决方案,在想同样的事情,但是这段代码可以更清晰 – Netwave

+0

@DanielSanchez为什么不呢? 。给我你的建议,我会编辑它:-)我接受任何建议。不要犹豫:-) –

+1

你使用一个如果当代码是相同的,但changhing 1单个运算符,也使用itertools.izip和itertools.islice而不是zip会很好,所以你不会创建中间列表只是为了检查,我也只是返回百分比结果:) – Netwave

1

你想利用DIFF沿着轴线(0或1),然后看正值沿此轴的比例:

(np.diff(a, axis=1) > 0).mean(axis=1) 

同样可以为列差异进行有axis=0和平均。

我不知道为什么你要80%,而不是75%,为第一行,但如果你想,你可以这样做:

(np.diff(a, axis=1) > 0).sum(axis=1)/a.shape[1] 

和列:

(np.diff(a, axis=0) > 0).sum(axis=0)/a.shape[0] 
+0

@Camilleri你可以请完成这个答案是可调用的吗? –

+0

好吧,你可以定义一个返回我写的行的函数,这很简单。 –

1

这是我建立和按预期工作的功能

def merge(mat): 
    monotone = 0 
    matrix = numpy.copy(mat) 
    for i in range(4): 
    m_vertical = 4 if numpy.size(numpy.where(numpy.diff(matrix[:, i]) < 0)[0]) == 0 else numpy.where(numpy.diff(matrix[:, i]) < 0)[0][0]+1 
    m_horizontal = 4 if numpy.size(numpy.where(numpy.diff(matrix[i]) < 0)[0]) == 0 else numpy.where(numpy.diff(matrix[i]) < 0)[0][0]+1 
    monotone += (m_vertical + m_horizontal)*3.125 
    return monotone