在2d矩阵中查找值的索引

5 python optimization matrix

我有一个表格矩阵,

mymatrix=[[1,2,3],[4,5,6],[7,8,9]]
Run Code Online (Sandbox Code Playgroud)

我想得到索引,例如9,即(2,2).

到目前为止我试图做的事情.

for i,j in enumerate(mymatrix):
   for k,l in enumerate(j):
     if l==9:
         print i,k
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来做同样的事情.优化,任何人?提前致谢.

Rya*_*ing 7

如果您想要显示该值的所有位置,您可以使用以下列表理解val设置为您要搜索的任何内容

[(index, row.index(val)) for index, row in enumerate(mymatrix) if val in row]
Run Code Online (Sandbox Code Playgroud)

例如:

>>> mymatrix=[[1,2,9],[4,9,6],[7,8,9]]
>>> val = 9
>>> [(index, row.index(val)) for index, row in enumerate(mymatrix) if val in row]
[(0, 2), (1, 1), (2, 2)]
Run Code Online (Sandbox Code Playgroud)

编辑

这种情况并非如此,它只会在给定的行中获得第一次出现的值.


rtr*_*ker 7

如果将mymatrix转换为numpy数组,则可以使用numpy.where返回索引:

>>> import numpy as np
>>> mymatrix=[[1,2,3],[4,5,6],[7,8,9]]
>>> a = np.array(mymatrix)
>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> b = np.where(a==9)
>>> b
(array([2]), array([2]))
>>> mymatrix=[[1,2,3],[9,5,6],[7,8,9]]
>>> a = np.array(mymatrix)
>>> a
array([[1, 2, 3],
       [9, 5, 6],
       [7, 8, 9]])
>>> b = np.where(a==9)
>>> b
(array([1, 2]), array([0, 2]))
Run Code Online (Sandbox Code Playgroud)


mar*_*eau 5

这是迄今为止发布的所有答案的基准,包括我自己的两个答案。我认为您可能会发现这些结果有用、有启发性,甚至可能令人惊讶。;¬)

请注意,如果数据是随机的,我已将目标值放在矩阵的中间以模拟其平均位置,以努力为找到后立即停止的算法平衡竞争环境(一点点) - 比较仍然不是'然而,这真的很公平。

在 Python 2 和 3 下运行。

更新- 添加了上次更新后发布的答案。

from __future__ import print_function
import numpy as np
import sys
from textwrap import dedent
import timeit

EXECUTIONS = 1000000  # Number of times each algorithm is executed per timing run.
TIMINGS = 3  # Number of timing runs.

SETUP = dedent("""
    # Make accessible in algorithms.
    from __main__ import np
    mymatrix=[[1,2,3], [4,9,6], [7,8,5]]  # Target value in middle.
    val = 9  # Target value.
""")

algorithms = {
    "user2459905 (OP) - all occurrences": dedent("""
        # finds all occurrences
        found = []
        for i,j in enumerate(mymatrix):
           for k,l in enumerate(j):
             if l==val:
                 found.append((i,k))
    """),

    "ayush thakur (fixed) - all occurrences": dedent("""
        # finds all occurrences
        found = []
        for i, e in enumerate(mymatrix):
            for j, ee in enumerate(e):
                if val == ee:  # Fixed.
                    found.append((i, j))
    """),


    "martineau #1 - all occurrences": dedent("""
        # finds all occurrences
        width = len(mymatrix[0])
        found = []
        posn = 0
        for row in mymatrix:
            if val not in row:
                posn += width
            else:
                for col in row:
                    if col == val:
                        found.append((posn // width, posn % width))
                    posn += 1
    """),

    "martineau #2 - all occurrences": dedent("""
        # finds all occurrences
        width = len(mymatrix[0])
        found = []
        posn = 0
        for row in mymatrix:
            if val in row:
                for y,col in enumerate(row):
                    if col == val:
                        found.append((posn // width, y))
            posn += width
    """),

    "mmtauqir - first occurrence": dedent("""
        # finds all occurrences
        matrix_dim = len(mymatrix[0])
        item_index = 0
        for row in mymatrix:
            for i in row:
                if i == val:
                    break
                item_index += 1
            if i == val:
                break
        found = (int(item_index / matrix_dim), item_index % matrix_dim)
    """),

    "rtrwalker - all occurrences using numpy": dedent("""
        # finds all occurrences using numpy
        a = np.array(mymatrix)  # Convert mymatrix to a numpy array.
        found = np.where(a==val)
    """),

    "Ryan Haining - first occurrence (per row)": dedent("""
        # finds first occurrence in each row
        found = [(index, row.index(val)) for index, row in enumerate(mymatrix)
                                            if val in row]
    """),

}


# Benchmark algorithms
timings = [
        (label, min(timeit.repeat(algorithms[label], setup=SETUP,
                                  repeat=TIMINGS, number=EXECUTIONS)))
            for label in algorithms
    ]

# Display metrics.
longest = max(len(timing[0]) for timing in timings)  # Length of longest label.

print('Fastest to slowest execution speeds with {}-bit Python {}.{}.{}'.format(
        64 if sys.maxsize > 2**32 else 32, *sys.version_info[:3]))
print('  with numpy version {}'.format(np.version.full_version),
      '-> {:,d} executions, best of {:,d})'.format(EXECUTIONS, TIMINGS))
print()

ranked = sorted(timings, key=lambda t: t[1])  # sort by speed (fastest first)
for timing in ranked:
    print("{:>{width}} : {:.6f} secs, rel speed {rel:6.3f}x".format(
          timing[0], timing[1], rel=timing[1]/ranked[0][1], width=longest))

Run Code Online (Sandbox Code Playgroud)

结果:

Fastest to slowest execution speeds with 32-bit Python 2.7.18
  with numpy version 1.16.6 -> 1,000,000 executions, best of 3)

              mmtauqir - first occurrence : 0.667560 secs, rel speed  1.000x
Ryan Haining - first occurrence (per row) : 0.694786 secs, rel speed  1.041x
           martineau #1 - all occurrences : 0.752011 secs, rel speed  1.127x
           martineau #2 - all occurrences : 0.929674 secs, rel speed  1.393x
   ayush thakur (fixed) - all occurrences : 1.541785 secs, rel speed  2.310x
       user2459905 (OP) - all occurrences : 1.544341 secs, rel speed  2.313x
  rtrwalker - all occurrences using numpy : 3.334727 secs, rel speed  4.995x


Fastest to slowest execution speeds with 32-bit Python 3.8.8
  with numpy version 1.21.1 -> 1,000,000 executions, best of 3)

              mmtauqir - first occurrence : 0.734707 secs, rel speed  1.000x
Ryan Haining - first occurrence (per row) : 0.749999 secs, rel speed  1.021x
           martineau #2 - all occurrences : 0.820354 secs, rel speed  1.117x
           martineau #1 - all occurrences : 0.880883 secs, rel speed  1.199x
       user2459905 (OP) - all occurrences : 1.436644 secs, rel speed  1.955x
   ayush thakur (fixed) - all occurrences : 1.638413 secs, rel speed  2.230x
  rtrwalker - all occurrences using numpy : 5.713464 secs, rel speed  7.777x

Run Code Online (Sandbox Code Playgroud)