簡體   English   中英

Python數組切片—如何實現2D數組切片?

[英]Python array slicing — How can 2D array slicing be implemented?

我想知道如何在Python中實現2D數組切片嗎?

例如,

arr是自定義類2D數組的實例。

如果要在此對象上啟用2D切片語法,如下所示:

arr[:,1:3] #retrieve the 1 and 2 column values of every row

要么

arr[,:3] #retrieve the 1 and 2 column values of every row

用法和語法類似於numpy.array。 但是如何獨自實現這種功能呢?

PS:

我的想法:

對於第一種情況, [:,1:3]部分就像兩個切片的元組

但是,對於第二種情況, [,1:3]似乎很神秘。

如果您想了解數組切片的規則,下圖可能會有所幫助:

在此處輸入圖片說明

對於讀取訪問,您需要重寫__getitem__方法:

class ArrayLike(object):
    def __init__(self):
        pass
    def __getitem__(self, arg):
        (rows,cols) = arg # unpack, assumes that we always pass in 2-arguments
        # TODO: parse/interpret the rows/cols parameters,
        # for single indices, they will be integers, for slices, they'll be slice objects
        # here's a dummy implementation as a placeholder 
        return numpy.eye(10)[rows, cols]

棘手的一點是__getitem__總是只使用一個參數(除self之外),當您將多個用逗號分隔的項目放在方括號內時,實際上是在提供一個元組作為__getitem__調用的參數。 因此,需要在函數內部拆開該元組的包裝(並可選地驗證元組的長度合適)。

現在給定a = ArrayLike() ,您最終得到

  • a[2,3]表示rows=2rows=2 cols=3
  • a[:3,2]表示rows=slice(None, 3, None)cols=3

等等; 您必須查看切片對象文檔,以確定如何使用切片信息從類中提取所需的數據。

為了使其更像一個numpy數組,您還希望覆蓋__setitem__ ,以允許分配給元素/切片。

obj[,:3]是無效的python,因此會引發SyntaxError -因此,您的源文件中不能包含該語法。 (當您嘗試在numpy數組上使用它時,也會失敗)

如果這是您自己的課程,並且願意傳遞字符串,這是一種技巧。

如何重寫[]運算符?

class Array(object):

    def __init__(self, m, n):
        """Create junk demo array."""
        self.m = m
        self.n = n
        row = list(range(self.n))
        self.array = map(lambda x:row, range(self.m))

    def __getitem__(self, index_string):
        """Implement slicing/indexing."""

        row_index, _, col_index = index_string.partition(",")

        if row_index == '' or row_index==":":
            row_start = 0
            row_stop = self.m
        elif ':' in row_index:
            row_start, _, row_stop = row_index.partition(":")
            try:
                row_start = int(row_start)
                row_stop = int(row_stop)
            except ValueError:
                print "Bad Data"
        else:
            try:
                row_start = int(row_index)
                row_stop = int(row_index) + 1
            except ValueError:
                print "Bad Data"

        if col_index == '' or col_index == ":":
            col_start = 0
            col_stop = self.n
        elif ':' in col_index:
            col_start, _, col_stop = col_index.partition(":")
            try:
                col_start = int(col_start)
                col_stop = int(col_stop)
            except ValueError:
                print "Bad Data"
        else:
            try:
                col_start = int(col_index)
                col_stop = int(col_index) + 1
            except ValueError:
                print "Bad Data"

        return map(lambda x: self.array[x][col_start:col_stop],
                       range(row_start, row_stop))

    def __str__(self):
        return str(self.array)

    def __repr__(self):
        return str(self.array)


array = Array(4, 5)
print array
out: [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]

array[",1:3"]
out: [[1, 2], [1, 2], [1, 2], [1, 2]]

array[":,1:3"]
out: [[1, 2], [1, 2], [1, 2], [1, 2]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM