簡體   English   中英

Python:基於多個子集更改數組元素的值

[英]Python: changing the value of array elements based on multiple subsets

我試圖基於一個子集的一個子集來修改數組的值,但是我找不到一種方法。 我認為這暴露了我對數組索引和子集的工作原理以及視圖的確切性的了解,但是我在任何地方都找不到解決方案,因此我希望有人可以幫助我。

問題示例:

import numpy as np

#generate some simple data
MyArray=np.arange(20).reshape(4,5)

>>>MyArray
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])

#subset 1
i=np.where(MyArray > 5)

#subset of that subset
j=np.where(MyArray[i] < 15)

>>>MyArray[i][j]
array([ 6,  7,  8,  9, 10, 11, 12, 13, 14])

太好了,這就是我期望看到的! 但是,如果現在我想將這些值更改為其他值,則不能:

>>>MyArray[i][j]=999
>>>MyArray[i][j]
array([ 6,  7,  8,  9, 10, 11, 12, 13, 14])

#hmmmm :(

一個有效的丑陋解決方案

我可以通過分別遍歷j的元素來獲取要更改的值,但這似乎非常笨拙且難以閱讀:

#get number of elements in j
nj=np.size(j)

#loop over each element of j and modify the corresponding ith element 
of MyArray 
for j_it in range(0,nj):
    MyArray[i[0][j[0][j_it]]][i[1][j[0][j_it]]]=999

>>>MyArray
array([[  0,   1,   2,   3,   4],
       [  5, 999, 999, 999, 999],
       [999, 999, 999, 999, 999],
       [ 15,  16,  17,  18,  19]])

同樣,我可以只使用一級子集修改MyArray

ii=np.where((MyArray > 5) & (MyArray < 15))
MyArray[ii]=999
>>>MyArray
array([[  0,   1,   2,   3,   4],
       [  5, 999, 999, 999, 999],
       [999, 999, 999, 999, 999],
       [ 15,  16,  17,  18,  19]])

那么,第一個示例在哪里出問題?

注意:-我知道我的最后一個解決方案可以很好地解決此問題,但是我的實際問題必然涉及更多的數據和第二級子集(可能還有第三級子集)。

在此先感謝您,如果這很簡單,我很抱歉可以從文檔中自行解決:我只是無法:(

如您所說,您的最后一個示例解決了您的問題。 您缺少的問題是調用MyArray[i]創建一個新數組,然后使用MyArray[i][j]再次建立索引。 當您嘗試分配該子集的結果時,實際上並沒有分配給MyArray

要執行與第一個示例類似的操作,您希望通過一個操作來完成所有操作,如下所示:

import numpy as np

#generate some simple data
MyArray=np.arange(20).reshape(4,5)

>>>MyArray
MyArray([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])

#subset 1
i=np.where(MyArray > 5)

#subset of that subset
j=np.where(MyArray[i] < 15)

# Mask array subset
MyArray[i[0][j[0]], i[1][j[0]]] = 999

>>>MyArray
MyArray([[  0,   1,   2,   3,   4],
   [  5, 999, 999, 999, 999],
   [999, 999, 999, 999, 999],
   [ 15,  16,  17,  18,  19]])

基本上, ij都是包含數組的元組,這些數組指示在where語句中匹配了哪些索引。 i包含兩個數組, MyArray每個維度一個。 j包含用於包含在所述陣列的單個維度一個陣列i 你想獲得j[0]這兩個數組的元素在i

希望這是有道理的。 如果您有任何問題,請告訴我。

嘗試創建布爾數組:

condition_1 = MyArray > 5
condition_2 = MyArray < 15

然后,您可以使用按位

bools = condition1 & condition2

其值如下:

[[ False,  False,  False,  False,  False],
   [ True,  True,  True,  ...]...]

如果此類數組的長度與您要更改數據的數組的長度相同,則可以在使用索引時使用它。 但是在這里,根據單元格是否滿足條件,您可以使用True或False來代替索引。

MyArray[bools] = 999

我認為@Vorticity的其他答案顯然是正確的,並且是經過深思熟慮的解釋,我認為不同的代碼段更具可讀性和可理解性。

https://docs.scipy.org/doc/numpy/reference/produced/numpy.where.html中,我們可以告訴np在第一個arg到np.where的布爾值之后對要使用的值進行評估。

>>>np.where((MyArray > 5) & (MyArray < 15), MyArray, 999)

array([[999, 999, 999, 999, 999],
   [999,   6,   7,   8,   9],
   [ 10,  11,  12,  13,  14],
   [999, 999, 999, 999, 999]])

話雖如此,“不分配給MyArray問題”的一個很好的例子如下:

>>> MyArray
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
>>> MyArray = MyArray[i]
>>> MyArray
array([ 6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>> MyArray = MyArray[j]
>>> MyArray
array([ 6,  7,  8,  9, 10, 11, 12, 13, 14])

我認為讓很多人(包括我自己)絆倒的主要事情是,僅調用MyArray[i]而不將其分配給帶有=東西不會使計算機把握小於或大於比較的結果是什么。

maskedarray看起來像具有正確的工具集

import numpy.ma as ma


MyArray=np.arange(20).reshape(4,5)

subma = ma.masked_inside(MyArray, 5, 15)  # lots of ma. logic, arithematic ops

subma.filled(999)

Out[44]: 
array([[  0,   1,   2,   3,   4],
       [999, 999, 999, 999, 999],
       [999, 999, 999, 999, 999],
       [999,  16,  17,  18,  19]])

暫無
暫無

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

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