#python #numpy #for-loop #variables
#python #numpy #для цикла #переменные
Вопрос:
Я проверил некоторые предыдущие вопросы, но, похоже, не могу получить ответ, хотя я не удивлюсь, если об этом спрашивали раньше. Я хотел бы выполнить некоторые вычисления для элементов массива, которые я индексирую с помощью цикла for.
У меня есть два массива:
S = [[4.21287783e-03 7.83625813e-03 1.42038926e-02 ... 3.15416197e-03
1.37110355e-03 9.45473448e-04]
[1.94774282e-03 1.36746081e-03 1.23485391e-03 ... 6.21054272e-04
5.31808587e-04 1.78796272e-04]
[1.20601337e-03 2.81822793e-04 6.32125664e-04 ... 2.72966598e-04
3.88162201e-04 1.89432902e-04]
...
[7.39537451e-05 1.20665168e-04 1.54863119e-04 ... 3.05247233e-04
2.26473099e-04 1.56650857e-04]
[9.29507556e-05 6.45091024e-05 9.84829924e-05 ... 3.07827294e-04
2.33815251e-04 1.52187484e-04]
[4.66322444e-05 3.16681323e-05 7.08467828e-05 ... 1.44890351e-04
7.91870831e-05 5.80408583e-05]]
frames = [ 1 2 3 4 5 6 7 8 9 ]
Я перебираю свой массив фреймов, но хочу итеративно выполнить вычисление для одного значения (индексируемого с помощью i) из массива S:
for i in frames:
np.log(S[:,i])
Но я получаю ошибку out-of-bounds (‘индекс 9 выходит за пределы оси 1 с размером 9’), потому что я индексирую до конца кадров. Я пытался:
np.log(S[:,(i-1)])
что не сработало — либо потому, что мой синтаксис неправильный, либо моя логика неправильная.
Я также пробовал:
for i in frames:
i=i-1
np.log(S[:,i])
И получите ту же ошибку out of bounds.
РЕДАКТИРОВАТЬ: я уверен, что могу вызвать S таким образом, потому что я делаю это в другом месте скрипта (и могу заменить любое целое число для i и запуска скрипта). Моя логика использования i в качестве индекса неверна.
Ответ №1:
С двумя списками, которые вы определяете (вы пишете о arrays
том, но копирование-вставка вашего кода создает списки):
In [30]: S = [23, 23.3, 34.2, 235, 23.1, 32.1, 23, 75, 4]
...: frames = [1, 2, 3, 4, 5, 6, 7, 8, 9]
In [31]: for i in frames:
...: print(S[:,i])
...:
TypeError: list indices must be integers or slices, not tuple
Вы не можете использовать [:,i]
индексацию со списками.
In [32]: for i in frames:
...: print(S[i])
..:
23.3
34.2
235
23.1
32.1
23
75
4
---------------------------------------------------------------------------
IndexError: list index out of range
При frames
этом вы пропускаете первый элемент S
и получаете ошибку с последним индексом. Индексация Python начинается с 0!
Даже если я создам массив numpy, ваша индексация будет неправильной:
In [33]: arr = np.array(S)
In [34]: for i in frames:
...: print(arr[:,i])
...:
IndexError: too many indices for array
arr
равно 1d, shape (9,) . Вы не можете использовать [:,i]` с этим.
Вы хотите выбрать часть S
(или arr
), например, первые 3 элемента?
In [36]: arr[:3]
Out[36]: array([23. , 23.3, 34.2])
In [37]: np.log(arr[:3])
Out[37]: array([3.13549422, 3.14845336, 3.53222564])
[:3]
индексы a slice
(как для списка, так и для массивов)
Если массив 2d, то вы можете использовать [:,i]
обозначение:
In [38]: A = arr.reshape(3,3)
In [39]: A
Out[39]:
array([[ 23. , 23.3, 34.2],
[235. , 23.1, 32.1],
[ 23. , 75. , 4. ]])
In [40]: A[:,0] # first column
Out[40]: array([ 23., 235., 23.])
Комментарии:
1. Спасибо, что нашли время, чтобы пройти через это. Я действительно неправильно идентифицировал структуру данных (теперь отредактировано). И я уточнил: я хочу получить журнал только одного элемента S (проиндексированного с помощью i). Как мне избежать ошибки out of bounds?
2. Обычно индекс
i
создается в пределах границ. ЕслиS
имеет форму(n,)
(n
элементы),frame
будет все или некоторое подмножество[0...8]
. Это то, чтоrange(n)
np.arange(n)
делает or. Другими словами,frame
создается с полным знанием массива, который он будет индексировать. Если элементframe
слишком велик, вы должны решить, что это значит — это ошибка, вы обрезаете его на максимально допустимом уровне, или он обтекается, или какая-то другая магия?3. Понял. Похоже, что это более серьезная проблема с моей структурой данных, и я, возможно, делал некоторые неправильные предположения о вычислениях, которые я делал в другом месте скрипта. По крайней мере, я рад узнать, что мой синтаксис не был отключен. Спасибо за ваше время.
Ответ №2:
Вы можете удалить «9» в массиве кадров, и вы увидите результат, как показано ниже:
23.3
34.2
235
23.1
32.1
23
75
4
Итак, теперь вы знаете, что индекс массива начинается с 0, а не с 1.
если вы хотите это исправить, вам нужно заменить массив frames:
frames = [0, 1, 2, 3, 4, 5, 6, 7, 8]
Ответ №3:
У вас есть лишняя запятая.
Попробуйте это:
for i in frames:
np.log(S[:i])
Мой тест:
$ python3
Python 3.7.2 (default, Feb 27 2019, 15:41:59)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> S = [23, 23.3, 34.2, 235, 23.1, 32.1, 23, 75, 4]
>>> frames = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for i in frames:
... print(S[:i])
...
[23]
[23, 23.3]
[23, 23.3, 34.2]
[23, 23.3, 34.2, 235]
[23, 23.3, 34.2, 235, 23.1]
[23, 23.3, 34.2, 235, 23.1, 32.1]
[23, 23.3, 34.2, 235, 23.1, 32.1, 23]
[23, 23.3, 34.2, 235, 23.1, 32.1, 23, 75]
[23, 23.3, 34.2, 235, 23.1, 32.1, 23, 75, 4]
>>>
Ответ №4:
Лично я думаю, что вам не нужно использовать frames
для индексации S
. Вы можете попробовать этот способ:
for i in range(S.shape[0])
np.log(S[i])
Комментарии:
1. ‘frames’ — это просто псевдомассив. Фактические «фреймы» представляют собой гораздо более сложный массив, составленный из переменных, определенных в другом месте скрипта. Так что, к сожалению, это не так просто, как просто посмотреть на длину S.
2.
S.shape
По сути,(9, )
вы используете S[:,i] (2d index) для индексации 1d массива . Я думаю, это неправильно.3. Я не знаю, что вы имеете в виду под определенной частью массива S. Потому что, если S — это список, его часть легко вывести
S
. Например, первая-третья частьS
S[0:3]
, по крайней мере, без точки «,» .4. Это не список, это 2D-массив.