Python - 反转数组的所有其他切片

Asi*_*sik 1 python

我编写了一些代码来反转每隔一行的行。

import numpy as np
test_arr = np.arange(120).reshape(12,10)
test_arr = test_arr.tolist()
def rev_rows(matrix):
    for I in range(len(matrix)): #did this to get the index of each row
        if((int(I / 4) % 2) == True): #selct rows whose index divided by 4 truncate to an odd number
            print("flip")
            matrix[I].reverse() #flip said row
        print(matrix[I])

rev_rows(test_arr)
Run Code Online (Sandbox Code Playgroud)

必须有一种更简单、更有效的方法来做到这一点。我在想另一种方法是使用切片等列表运算符,但我想不出比这更快的方法。numpy 有更简单的方法吗?

注意:矩阵的长度可以被 4 整除。即 (4x10), (8x10), ...

编辑:

很抱歉切片的用法不明确。我所说的切片是一组行(例如 test_arr[3] -> test_arr[7])。因此,反转所有其他切片将反转索引 3 和 7 之间的每一行。我在关于切片运算符的小简介中我正在谈论这个运算符 -> [3:7]。我没有使用它们的经验,我在某处读到它们被称为切片,我的错。

Bla*_*ans 6

更新

问题不是很清楚,所以我原来的回答没有解决问题。这是一个工作示例。

带循环

循环版本的性能更可预测,因为并不总是清楚重塑何时会触发复制。

>>> test_arr = np.arange(120).reshape(12, 10)
>>> for i in range(4, 8):
...     test_arr[i::8] = test_arr[i::8,::-1]
>>> test_arr
array([[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9],
       [ 10,  11,  12,  13,  14,  15,  16,  17,  18,  19],
       [ 20,  21,  22,  23,  24,  25,  26,  27,  28,  29],
       [ 30,  31,  32,  33,  34,  35,  36,  37,  38,  39],
       [ 49,  48,  47,  46,  45,  44,  43,  42,  41,  40],
       [ 59,  58,  57,  56,  55,  54,  53,  52,  51,  50],
       [ 69,  68,  67,  66,  65,  64,  63,  62,  61,  60],
       [ 79,  78,  77,  76,  75,  74,  73,  72,  71,  70],
       [ 80,  81,  82,  83,  84,  85,  86,  87,  88,  89],
       [ 90,  91,  92,  93,  94,  95,  96,  97,  98,  99],
       [100, 101, 102, 103, 104, 105, 106, 107, 108, 109],
       [110, 111, 112, 113, 114, 115, 116, 117, 118, 119]])
>>> 
Run Code Online (Sandbox Code Playgroud)

没有循环

正如@KellyBundy 所要求的,无循环版本。

>>> test_arr = np.arange(120).reshape(12, 10)
>>> temp_arr = test_arr.reshape(test_arr.shape[0]//4, 4, test_arr.shape[1])
>>> temp_arr[1::2] = temp_arr[1::2,:,::-1]
>>> test_arr = temp_arr.reshape(*test_arr.shape)
>>> test_arr
array([[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9],
       [ 10,  11,  12,  13,  14,  15,  16,  17,  18,  19],
       [ 20,  21,  22,  23,  24,  25,  26,  27,  28,  29],
       [ 30,  31,  32,  33,  34,  35,  36,  37,  38,  39],
       [ 49,  48,  47,  46,  45,  44,  43,  42,  41,  40],
       [ 59,  58,  57,  56,  55,  54,  53,  52,  51,  50],
       [ 69,  68,  67,  66,  65,  64,  63,  62,  61,  60],
       [ 79,  78,  77,  76,  75,  74,  73,  72,  71,  70],
       [ 80,  81,  82,  83,  84,  85,  86,  87,  88,  89],
       [ 90,  91,  92,  93,  94,  95,  96,  97,  98,  99],
       [100, 101, 102, 103, 104, 105, 106, 107, 108, 109],
       [110, 111, 112, 113, 114, 115, 116, 117, 118, 119]])
>>>
Run Code Online (Sandbox Code Playgroud)

原答案

您可以使用 slicing: test_arr[::2] = test_arr[::2,::-1]或 来完成此操作test_arr[1::2] = test_arr[1::2,::-1]

请参阅示例:

>>> import numpy as np
>>> test_arr = np.arange(120).reshape(12, 10)
>>> test_arr
array([[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9],
       [ 10,  11,  12,  13,  14,  15,  16,  17,  18,  19],
       [ 20,  21,  22,  23,  24,  25,  26,  27,  28,  29],
       [ 30,  31,  32,  33,  34,  35,  36,  37,  38,  39],
       [ 40,  41,  42,  43,  44,  45,  46,  47,  48,  49],
       [ 50,  51,  52,  53,  54,  55,  56,  57,  58,  59],
       [ 60,  61,  62,  63,  64,  65,  66,  67,  68,  69],
       [ 70,  71,  72,  73,  74,  75,  76,  77,  78,  79],
       [ 80,  81,  82,  83,  84,  85,  86,  87,  88,  89],
       [ 90,  91,  92,  93,  94,  95,  96,  97,  98,  99],
       [100, 101, 102, 103, 104, 105, 106, 107, 108, 109],
       [110, 111, 112, 113, 114, 115, 116, 117, 118, 119]])
>>> test_arr[::2] = test_arr[::2,::-1]
>>> test_arr
array([[  9,   8,   7,   6,   5,   4,   3,   2,   1,   0],
       [ 10,  11,  12,  13,  14,  15,  16,  17,  18,  19],
       [ 29,  28,  27,  26,  25,  24,  23,  22,  21,  20],
       [ 30,  31,  32,  33,  34,  35,  36,  37,  38,  39],
       [ 49,  48,  47,  46,  45,  44,  43,  42,  41,  40],
       [ 50,  51,  52,  53,  54,  55,  56,  57,  58,  59],
       [ 69,  68,  67,  66,  65,  64,  63,  62,  61,  60],
       [ 70,  71,  72,  73,  74,  75,  76,  77,  78,  79],
       [ 89,  88,  87,  86,  85,  84,  83,  82,  81,  80],
       [ 90,  91,  92,  93,  94,  95,  96,  97,  98,  99],
       [109, 108, 107, 106, 105, 104, 103, 102, 101, 100],
       [110, 111, 112, 113, 114, 115, 116, 117, 118, 119]])
>>> 
Run Code Online (Sandbox Code Playgroud)

相反,如果您想反转具有奇数索引的行,您可以这样做

>>> test_arr = np.arange(120).reshape(12, 10)
>>> test_arr[1::2] = test_arr[1::2,::-1]
>>> test_arr
array([[  0,   1,   2,   3,   4,   5,   6,   7,   8,   9],
       [ 19,  18,  17,  16,  15,  14,  13,  12,  11,  10],
       [ 20,  21,  22,  23,  24,  25,  26,  27,  28,  29],
       [ 39,  38,  37,  36,  35,  34,  33,  32,  31,  30],
       [ 40,  41,  42,  43,  44,  45,  46,  47,  48,  49],
       [ 59,  58,  57,  56,  55,  54,  53,  52,  51,  50],
       [ 60,  61,  62,  63,  64,  65,  66,  67,  68,  69],
       [ 79,  78,  77,  76,  75,  74,  73,  72,  71,  70],
       [ 80,  81,  82,  83,  84,  85,  86,  87,  88,  89],
       [ 99,  98,  97,  96,  95,  94,  93,  92,  91,  90],
       [100, 101, 102, 103, 104, 105, 106, 107, 108, 109],
       [119, 118, 117, 116, 115, 114, 113, 112, 111, 110]])
>>> 
Run Code Online (Sandbox Code Playgroud)