Кажется, что преобразование в список и обратно будет неэффективным. Вместо этого, почему бы не выяснить, какой массив индексировать (и где), а затем просто обновлять этот индекс? например
def change_element(arr1, arr2, ix, value):
which = ix >= arr1.size
arr = [arr1, arr2][which]
ix = ix - arr1.size if which else ix
arr.ravel()[ix] = value
И вот несколько примеров использования:
>>> arr1 = np.zeros((2, 2))
>>> arr2 = np.ones((3, 3))
>>> change_element(arr1, arr2, 1, 2)
>>> change_element(arr1, arr2, 6, 3.14)
>>> arr1
array([[ 0., 2.],
[ 0., 0.]])
>>> arr2
array([[ 1. , 1. , 3.14],
[ 1. , 1. , 1. ],
[ 1. , 1. , 1. ]])
>>> change_element(arr1, arr2, 7, 3.14)
>>> arr1
array([[ 0., 2.],
[ 0., 0.]])
>>> arr2
array([[ 1. , 1. , 3.14],
[ 3.14, 1. , 1. ],
[ 1. , 1. , 1. ]])
Несколько заметок - Это обновляет массивы на месте. Он не создает новые массивы. Если вам действительно нужно создавать новые массивы, я полагаю, вы могли бы np.copy
их и вернуться. Кроме того, это зависит от памяти обмена массивами до и после ravel
. Я не помню точных обстоятельств, когда ravel
вернул новый массив, а не представление в исходный массив. , ,
Обобщение на большее количество массивов на самом деле довольно просто. Нам просто нужно спуститься по списку массивов и посмотреть, меньше ли размер ix
. Если это так, мы нашли наш массив.Если это не так, мы должны вычесть размер массива из ix
для представления числа элементов, мы пересекали до сих пор:
def change_element(arrays, ix, value):
for arr in arrays:
if ix < arr.size:
arr.ravel()[ix] = value
return
ix -= arr.size
И вы можете назвать это похоже на перед:
change_element([arr1, arr2], 6, 3.14159)
Nice. Но это решение ограничено ровно двумя массивами. Было бы интересно обобщить его на список массивов с неопределенным количеством массивов. –
@ MikeMüller - Конечно. Обобщение довольно просто (достаточно просто, чтобы добавить его в качестве дополнения к решению). – mgilson
@mgilson Большое спасибо. Я думаю, что это решение может решить мою проблему. – tuming1990