Например, скажем, я имитируя кучу частиц делать что-то в течение долгого времени, и у меня есть многомерный массив называется particles
с этими индексами:Порядок индексов в многомерном массиве Numpy
- X/у/Z координата частицы (длины
a
, который3
для 3D пространства) - индекса отдельной частицы (длины
b
) - индекса временного шага он находится на (длины
c
)
Лучше ли построить такой массив, что particles.shape == (a, b, c)
или particles.shape == (c, b, a)
?
Я больше заинтересован в согласии, чем в эффективности: массивы Numpy могут быть настроены либо в C-стиле (последний индекс меняется наиболее быстро), либо в стиле Fortran (первый индекс), поэтому он может эффективно поддерживать любую настройку. Я также понимаю, что могу использовать transpose
, чтобы поместить индексы в любом порядке, в котором я нуждаюсь, но я хотел бы свести это к минимуму.
Я начал исследовать это сам и нашел поддержку обоих способов:
Pro- (с, Ь, а):
- По умолчанию Numpy использует массивы C-стиле, где последний индекс является самым быстрым.
- Большинство функций векторной алгебры (
inner
,cross
и т. Д.) Действуют на последний индекс. (dot
действует на последнем и втором и на последнем.) - Объекты коллекции
matplotlib
(LineCollection
,PolyCollection
) ожидают массивы с пространственными координатами на последней оси.
Pro- (а, б, в):
- Если я должен был использовать
meshgrid
иmgrid
производить множество точек, было бы поставить пространственную ось первой. Например,np.mgrid[0:5,0:5,0:5].shape == (3,5,5,5)
. Я понимаю, что эти функции в основном предназначены для integer array indexing, но это не редкость использовать их для создания сетки точек. - В
matplotlib
scatter
иplot
функции разделить свои аргументы, так что агностик в форме массива, ноax.plot3d(particles[0], particles[1], particles[2])
короче набирать, чем версия сparticles[..., 0]
В целом представляется, что есть две разные (вероятно, из-за исторических различий между C и Fortran), и неясно, что более распространено в сообществе Numpy, или более подходящим для того, что я делаю.
Фактически, это имеет эффект ... сравните 'x = np.ones ((3,4,5)); y = np.linalg.norm (x, axis = 0) 'to' x = np.ones ((5,4,3)); y = np.linalg.norm (x, axis = -1) '. Сначала с пространственным индексом, 'x/y' нормализует' x' без какого-либо сгибания индекса. С последним пространственным индексом вы должны сделать что-то вроде 'x/y [..., np.newaxis]' – Apocheir
. Ряд методов «сокращения» (например, 'sum',' mean') имеет 'keepdims' чтобы исключить необходимость добавления этого «newaxis» обратно. – hpaulj