我有一个形状为Ax2
的直角坐标数组,其中A
是一个任意数。这里有一个我正在谈论的例子:
>>> np.arange(20).reshape(10, 2)
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11],
[12, 13],
[14, 15],
[16, 17],
[18, 19]])
字符串
我想将每个沿着轴0的两个值的数组转换为极坐标数组(也是两个值)。所以末端数组的形状也应该是Ax2
。下面是我想要的输出示例:
>>> a = np.arange(20).reshape(10, 2)
>>> toPolar(a)
[[ 1. 1.57079633]
[ 3.60555128 0.98279372]
[ 6.40312424 0.89605538]
[ 9.21954446 0.86217005]
[12.04159458 0.84415399]
[14.86606875 0.83298127]
[17.69180601 0.82537685]
[20.51828453 0.81986726]
[23.34523506 0.81569192]
[26.17250466 0.81241861]]
型
我通过按列拆分数组来获得x值和y值的数组,然后将这两个数组传递给通用直角坐标到极坐标函数的向量化形式,从而使以下代码工作。然而,最后一步给出了一个形状为2xA
的数组,所以我需要将它转置回Ax2
:
def toPolar(arr):
def rect2polar(x, y):
r = math.sqrt(x**2 + y**2)
ang = math.atan2(y, x)
return (r, ang)
vect = np.vectorize(rect2polar)
p = vect(r[:, 0], r[:, 1]) # splits coords up and returns in 2x10 array
p = np.transpose(p) # converts from 2x10 back to 10x2
return p
型
我认为拆分数组然后再转置是很慢的。
有没有办法跳过转置步骤,让np.vectorize
创建一个以数组为输入的函数,这样我就可以沿着轴0运行向量化的函数?
2条答案
按热度按时间7ajki6be1#
你需要做的就是使用
numpy
函数,而不是vectorize
:字符串
结果是2个数组,但它们很容易与
np.transpose
组合:型
顺便说一下,
np.argwhere
使用相同的技巧将np.nonzero
数组变成一个。得到
x,y
的另一种方法是x,y = arr.T
。看看x.base
,我们看到x
只是原始arange
的view
。所以这是有效率的。组合结果数组的另一种方法是:
np.array(rect2polar(arr[:,0],arr[:,1])).T
.这个稍微快一点。但与您的math
和vectorize
版本相比,这些组合方法中的任何一种都很快。使用
math
函数,使用vectorize
比直接的列表解析要慢:型
作为一般规则,
math
函数对于单个数字比等效的np
更快。但对于阵列,np
更快。尽管交叉点可以变化。wgmfuz8q2#
为了回答你的部分问题,不幸的是,我认为不可能直接将函数应用于数组“沿着轴0”而不引起某种(可能是隐藏的)Python级别的循环。问题是,大多数有用的numpy内置函数都单独使用它们的参数,而不是沿着数组中的维度。
从这个意义上说,将数据处理为一对
x, y
变量(每个变量的形状为A
)而不是A x 2
形状的数组可能更自然:字符串
用于转换为polar的相关numpy函数是
np.hypot
和np.arctan2
。简单地说:型
话虽如此,有一些方法可以摆弄形状,使它们以你想要的方式对齐。例如,你可以通过
hsplit
从a
中提取x
和y
作为形状A x 1
,然后通过hstack
将它们返回到A x 2
数组:型