英文:
Slice a 2D array using built-in slice function
问题
我需要编写一个函数,该函数从二维数组中返回单行或单列。函数的输入告诉它要返回什么。
# 值为1到9的3x3数组
a = np.arange(1, 10).reshape(3,3)
rowCount, colCount = a.shape
# 返回最后一行 [7, 8, 9]
a[rowCount - 1, :]
# 返回第一行 [1, 2, 3]
a[0, :]
# 返回最后一列 [3, 6, 9]
a[:, lastCol]
# 返回第一列 [1, 4, 7]
a[:, 0]
如何在函数中实现这个功能,以便函数接收要返回的行或列?
类似于:
def getSlice(slice):
return a[slice]
然而,我无法弄清楚如何为二维数组创建切片对象,因为 slice
函数不接受冒号操作符,比如 slice(0, :)
。
此外,是否有一种方法可以表示"最后一行"或"最后一列",如果我事先不知道二维数组的形状?
用例
以下是我需要函数而不是直接使用 a[:, 0]
表达式的几种用例:
- 调用者无法访问数组。调用者可以通过调用
getSlice
函数从数组中获取所需的行或列。 - 需要预先配置首选的行或列。例如,
{a1: '第一行',a2: '最后一列'}
。a1
和a2
可能会多次进行转置和修改。但在任何时候,我只对这两个数组的配置行/列感兴趣。
英文:
I need to write a function that returns a single row or a column from a 2D array. The input to the function tells what to return.
# 3x3 array with values 1 to 9
a = np.arange(1, 10).reshape(3,3)
rowCount, colCount = a.shape
# return last row [7, 8, 9]
a[rowCount - 1, :]
# return first row [1, 2, 3]
a[0, :]
# return last column [3, 6, 9]
a[:, lastCol]
# return first column [1, 4, 7]
a[:, 0]
How can I do this in a function, such that the function receives the row or column to return?
Something like,
def getSlice(slice):
return a[slice]
Where the slice object is created using the built-in slice function.
However, I cannot figure out how to create a slice object for a 2D array, due to the fact that slice
function does not accept the colon operator like slice(0, :)
.
Also, is there a way to represent "last row" or "last column if I do not know beforehand the shape of the 2D array?
Use-Case
Below are a couple of use-cases why I need a function instead of directly using the a[:, 0]
expression:
- The caller does not have access to the array. The caller can get a desired row or column from the array by calling the
getSlice
function. - The preferred row or column needs to be pre-configured. For instance,
{a1: 'first row', a2: 'last column'}
. Botha1
anda2
may get transposed and modified many times. But at all times, I am interested only in the configured row/column of the two arrays.
答案1
得分: 1
我将翻译代码之外的部分:
我将尝试稍微解释一下您的问题:
> 我无法弄清楚如何为二维数组创建一个切片对象,因为切片函数不接受冒号操作符,比如 slice(0, :)
确实,这是不起作用的,因为 slice
对象不是这样工作的:它们表示沿一个维度的索引范围,而您想要沿两个维度进行索引。因此,虽然单个 slice
对象不起作用,但您可以使用元组 - 参考文档这里,特别是 切片和步进 部分的最后一个项目:
> 切片元组始终可以构造为 obj 并在 x[obj]
表示法中使用。切片对象可以在构造中替代 [start:stop:step]
表示法。例如,x[1:10:5, ::-1]
也可以表示为 obj = (slice(1, 10, 5), slice(None, None, -1)); x[obj]
。
在您的情况下,因为您只要求完整的行和列:
> 我需要编写一个从二维数组中返回单行或单列的函数。
…相应的 :
可以写为 slice(None, None, None)
。事实上,您甚至不需要显式创建切片元组,因为您只会确切地有两个索引(一个用于行,一个用于列,其中一个是 :
),您可以直接用于索引数组。因此,如果您真的想将索引打包到一个函数中,我会创建一个如下的函数:
def get_slice(row=slice(None,None,None), col=slice(None,None,None)):
return a[row, col] # 或者等效地 a[(row, col)]
在这里,我们将 :
,或者更确切地说是等效的 slice(None,None,None)
,作为行和列的默认值,以便用户只需传递一个感兴趣的索引值。当然,您也可以调整函数,以便接受一个元组,这会更接近您的原始代码。
无论如何,上面的版本将为您提供:
print(get_slice(row=0)) # 第一行
# 输出:[1 2 3]
print(get_slice(col=-1)) # 最后一列
# 输出:[3 6 9]
print(get_slice(col=0)) # 第一列
# 输出:[1 4 7]
最后:
> 还有没有一种表示“最后一行”或“最后一列”的方法...?
您可以通过负索引来实现这一点,我在上面的示例中已经用于最后一列。负索引是从“右边”或“底部”开始计算的,因此 a[-1]
指的是最后一行,a[:, -2]
指的是倒数第二列等等,并且不需要知道数组的实际形状。
英文:
I will try to pick your question apart a bit:
> I cannot figure out how to create a slice object for a 2D array, due to the fact that slice function does not accept the colon operator like slice(0, :)
Indeed, this does not work, as slice
objects do not work like that: they represent the index range along one dimension, while you want to index along two dimensions. So, while this does not work with a single slice
object, you can use a tuple – compare the doc here, especially the last bullet point of the section Slicing and striding:
> A slicing tuple can always be constructed as obj and used in the x[obj]
notation. Slice objects can be used in the construction in place of the [start:stop:step]
notation. For example, x[1:10:5, ::-1]
can also be implemented as obj = (slice(1, 10, 5), slice(None, None, -1)); x[obj]
.
In your, case, as you only ask for complete rows and columns:
> I need to write a function that returns a single row or a column from a 2D array.
… the corresponding :
can be written as slice(None, None, None)
. In fact, you do not even need to explicitly create the slicing tuple, as you only ever will exactly have two indices (one for row, one for column, either of them being :
) that you can directly use for indexing your array. So, if you really want to pack your indexing into a function, I would create a function as follows:
def get_slice(row=slice(None,None,None), col=slice(None,None,None)):
return a[row, col] # or, equivalently a[(row, col)]
Here, we will provide :
, or rather, the equivalent slice(None,None,None)
, as the default value for both row and column, so that the users only need to pass one value for the index that they are actually interested in. Of course, you can also adjust the function so that a tuple is accepted instead, which would be closer to your original code.
In any case, the version above will give you:
print(get_slice(row=0)) # First row
# >>> [1 2 3]
print(get_slice(col=-1)) # Last column
# >>> [3 6 9]
print(get_slice(col=0)) # First column
# >>> [1 4 7]
Finally:
> Also, is there a way to represent "last row" or "last column" …?
You can achieve this with negative indexing, which I already used for the last column in the example above. Negative indexing works "from the right" or "from the bottom", thus a[-1]
refers to the last row, a[:, -2]
refers to the penultimate column, etc., and does not require knowing the actual shape of the array.
答案2
得分: -2
以下是翻译好的部分:
如果你想要获取 4 ->
a[1][0] -> 4
所以,如果你将其视为矩阵,那么该函数可以接受两个参数(x,y)
def get_element(matrix, x, y):
return matrix[x][y]
如果你想要获取列 - 那么我建议应用分离关注点原则:
def select_column(matrix, column_index):
selected_column = [row[column_index] for row in matrix]
return selected_column
test = select_column(a, 1) -> [2, 5, 8]
或者更加简洁的方式:
a[:,1]
英文:
While a is: [[1 2 3][4 5 6][7 8 9]].
a[0] -> [1 2 3]
a[1] -> [4 5 6]
a[2] -> [7 8 9]
if you wan't 4 ->
a[1][0] -> 4
So if you treat is as matrix then the function can accept 2 parameters (x, y)
def get_element(matrix, x, y):
return matrix[x][y]
If you wan't column - that there I suggest to apply separated method - due to Separation of Concerns principle:
def select_column(matrix, column_index):
selected_column = [row[column_index] for row in matrix]
return selected_column
test = select_column(a, 1) -> [2, 5, 8]
or in more concise manner:
a[:,1]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论