在Python中列出列表列表中的峰值高程

时间:2014-03-02 20:59:19

标签: python python-2.7

我需要定义一个函数来识别高程数据中的峰值。峰值定义为高于8个相邻值的值(上面三个,两侧各一个,下面三个)。

不允许导入

在以下数据中:87是峰值,因为它高于542,72,49,69,62,71,61

data = [ [20, 54, 50, 64, 60, 63, 60, 48, 20, 20],
     [20, 56, 72, 76, 72, 52, 62, 53, 20, 20],
     [20, 52, 62, 81, 67, 48, 67, 52, 23, 20],
     [20, 54, 54, 82, 72, 42, 64, 50, 22, 20],
     [20, 53, 49, 87, 69, 47, 48, 49, 21, 20],
     [20, 20, 62, 71, 61, 36, 28, 31, 22, 20],
     [20, 20, 20, 20, 20, 22, 21, 28, 24, 20],
     [20, 20, 20, 20, 20, 20, 20, 20, 20, 20],
     [20, 20, 20, 20, 20, 20, 20, 20, 20, 20],
     [20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
   ]

我已经知道如何去做,但不确定如何编写代码。

def peaks(list1):
    for item in list1:
        # if item > (item[row][column-1] and item[row][column+1] and item[row-1][column-1] and \
        # item[row-1][column] and item[row-1][column+1] and item[row+1][column-1] and item[row+1][column] and item[row+1][column+1]):

如何将评论的部分翻译成适当的python代码?

编辑:好的,为什么这不起作用?列表coords似乎被覆盖了,我无法弄清楚原因。

返回应该是:[(2,6),(4,3)]

def peaks(list1):
    for row in range(len(list1)):
        for column in range (len(list1[row])):
            if row != 0 and row != len(list1)-1 \
               and column != 0 and column != len(list1[row])-1:
                coords = []
                if max(list1[row-1][column-1:column+2] + \
                       [list1[row][column-1]] + [list1[row][column+1]] + \
                       list1[row+1][column-1:column+2]) < list1[row][column]:
                    coords.append((row, column))
                return coords

3 个答案:

答案 0 :(得分:2)

您可以使用一些特定于Python的习惯用法,并尝试使此代码更具可读性。让我们按如下方式划分问题:

  1. 给定矩阵,返回所有核心(非边界)索引;
  2. 给定矩阵核心内的坐标,返回包含其邻居坐标的列表;
  3. 给定一对或坐标和矩阵,检查它是否为峰值。
  4. 第一步可以实现如下:

    def core_indexes(matrix):
        row = matrix[0]
    
        lines = len(matrix)
        columns = len(row)
    
        for i in range(1, lines - 1):
            for j in range(1, columns - 1):
                yield i, j
    

    请注意,此方法没有返回值,而产生。产生的函数或方法是编写生成器的Pythonic形式,也就是说,每次调用时都返回一个系列的下一个术语的特殊函数。

    第二步更简单,让我们使用相同的技巧。

    def neighbor_indexes(i, j):
        for r in range(i - 1, i + 2):
            for c in range(j - 1, j + 2):
                if (i, j) != (r, c):
                    yield r, c
    

    我们应该做的下一步(第3步)是检查给定位置是否代表峰值。给定值是一个峰值,当且仅当它大于它的最大邻居时。让我们写下:

    def is_peak(i, j, matrix):
        max_neighbor = max([matrix[i][j] for i, j in neighbor_indexes(i, j)])
        return matrix[i][j] > max_neighbor
    

    请注意以下声明:

    [matrix[i][j] for i, j in neighbor_indexes(i, j)]
    

    它被称为列表理解。它被翻译为“构建一个由neighbor_indexes函数返回的矩阵[i,j] foreach i,j对的列表”。相当Pythonic。

    现在,是时候使用这些功能来扫描矩阵了。人们可以做到以下几点:

    for i, j in core_indexes(data):
        if is_peak(i, j, data):
            print("%d at [%d, %d] is a peak" % (data[i][j], i, j))
    

    它将打印:

    67 at [2, 6] is a peak
    87 at [4, 3] is a peak
    

    请注意,我们的索引是基于零的。

答案 1 :(得分:1)

由于这看起来像是家庭作业,我将给出两个提示,而不是提供完整的解决方案:

  1. 编写两个嵌套循环,一个用于行,一个用于列(仔细考虑循环边界应该是什么)。
  2. 要检查a是否大于bc,请写下a > b and a > c

答案 2 :(得分:0)

这是一个解决方案。我没有考虑边界中的值,因为你明确地说最大值应该大于&#34; 8&#34;邻居。

for idxR in range(len(data)):
    for idxC in range(len(data[idxR])):
        if idxR != 0 and idxR != len(data)-1 \
        and idxC != 0 and idxC != len(data[idxR])-1:
        if max(data[idxR-1][idxC-1:idxC+2] + 
               [data[idxR][idxC-1]] + [data[idxR][idxC+1]] + \
               data[idxR+1][idxC-1:idxC+2]) < data[idxR][idxC]:
            print '%d is a maximum' % data[idxR][idxC]

行。这是考虑你的评论的新版本,你说你想要有坐标。你的版本的问题是你在循环中重置 coords 的值并在循环遍历所有元素之前返回。 coords 应该在开头定义并在最后返回。

def peaks(list1):
    coords = []
        for row in range(len(list1)):
            for column in range (len(list1[row])):
                if row != 0 and row != len(list1)-1 \
                and column != 0 and column != len(list1[row])-1:
                    if max(list1[row-1][column-1:column+2] + \
                    [list1[row][column-1]] + [list1[row][column+1]] + \
                    list1[row+1][column-1:column+2]) < list1[row][column]:
                        coords.append((row, column))
        return coords