I have the the following array
import numpy as np
import CustomClass
# Total = 24
height = 4
width = 6
a = np.empty((height, width), dtype=object)
for row in range(self.height):
for col in range(self.width):
self.a[row, col] = CustomClass()
I would like to change the attribute for part of the array (filled with my custom class). For example, I would like to change 12 elements starting from element[0,0], then from row to row. Ideally, I would do something comparable to
change=11
for i in range(change):
a[i].value=True
The result would be something like the following (0: unchanged, x: changed)
x x x x x x
x x x x x 0
0 0 0 0 0 0
0 0 0 0 0 0
The problem with my array is that I first need to flatten it before I could do something like this. Or I should calculate how many columns and rows I before I can index the array itself. Is there a numpy function such that I can just iteratre over the array element by element (row by row).
I hope my explanation is clear?
CodePudding user response:
You can do this a couple of ways, but one approach would be to use np.unravel_index
to get the two-dimensional indices that correspond to the flattened one-dimensional ones. I'll show you how to do this below.
First create your data:
from dataclasses import dataclass
import numpy as np
height = 4
width = 6
@dataclass
class myClass:
value: bool = False
data = np.asarray([myClass() for _ in range(height * width)])
data = data.reshape(height, width)
Now, make change
an array of indices that you want to change, rather than the number of elements you want to change:
change = np.arange(11)
Determine the two-dimensional indices that correspond to those in change
:
rows, columns = np.unravel_index(indices=change, shape=(height, width))
And then you can use these indices to iterate over the elements you want to change:
for element in data[rows, columns]:
element.value = True
CodePudding user response:
You can use variable to count how many elements was changed and use break
to exit loops
import numpy as np
height = 4
width = 6
a = np.empty((height, width), dtype=object)
a[:] = '0'
count = 0
for row in range(height):
for col in range(width):
count = 1
a[row, col] = 'x'
if count == 11:
break
if count == 11:
break
print(a)
Result:
[['x' 'x' 'x' 'x' 'x' 'x']
['x' 'x' 'x' 'x' 'x' '0']
['0' '0' '0' '0' '0' '0']
['0' '0' '0' '0' '0' '0']]
To make it simpler you can set count = 11
at start and later substract until you get 0
.
This way you have to set 11
only in one place.
import numpy as np
height = 4
width = 6
a = np.empty((height, width), dtype=object)
a[:] = '0'
count = 11
for row in range(height):
for col in range(width):
count -= 1
a[row, col] = 'x'
if count == 0:
break
if count == 0:
break
print(a)
EDIT:
You could also calculate how many full rows you have to change and how many elements you have to change in last row.
import numpy as np
height = 4
width = 6
a = np.empty((height, width), dtype=object)
a[:] = '0'
count = 11
rows = count // width
rest = count % width
a[:rows] = 'x'
a[rows,:rest] = 'x'
print(a)
But this will not work if you want to start in different place then [0,0]