如何在python

时间:2016-10-21 20:07:19

标签: python arrays numpy set itertools

问题:

我需要将一个集转换为数组。如果我尝试只做np.array(X),我得到一个包含一个集合的数组,这不是很有用。如果我将我的集合转换为列表然后将我的列表转换为数组,一切正常,但这看起来不必要复杂(所讨论的代码行已经是一个复杂的不必要的复杂性)。有没有办法直接从set到array?

代码上下文,如果有帮助:

rad = 0.944
n = 5
pairs = np.array(list(set(chain.from_iterable(((x,y),(x,-y),(-x,y),(-x,-y)) for x in np.linspace(0, rad, n) for y in np.linspace(0, rad, n) if math.hypot(x,y) <= rad))))

该集合的要点是从链中删除重复项。我知道有一些方法可以用数组做到这一点,但似乎不可能将itertools.chain对象直接转换为数组。

从整体上讲,这段代码只是使用x,y点的均匀分布来模拟圆形,并通过唤起四个象限之间的对称来加速过程。

3 个答案:

答案 0 :(得分:1)

这是一种纯粹的Numpythonic方法:

In [244]: lins = np.unique(np.linspace(0, rad, n))
# Create the prucuct of lins
In [245]: arr = np.array((np.repeat(lins, 5), np.tile(lins, 5))).T
# remove extra items based on your condition
In [246]: new = np.compress(np.sqrt(np.power(arr, 2).sum(1)) <= 0.944, arr, 0)

In [247]: a = np.array([ 1, -1])
# Create a product of (-1, 1) for creating the total expected result by multiplying the product on each row of the compressed array
In [248]: perm = np.array((np.repeat(a, 2), np.tile(a, 2))).T

In [249]: total = new[:,None] * perm

请注意,如果您确保linspace数组中没有重复项,则总组合中不会有任何项。

以下是total结果:

array([[[ 0.   ,  0.   ],
        [ 0.   , -0.   ],
        [-0.   ,  0.   ],
        [-0.   , -0.   ]],

       [[ 0.   ,  0.236],
        [ 0.   , -0.236],
        [-0.   ,  0.236],
        [-0.   , -0.236]],

       [[ 0.   ,  0.472],
        [ 0.   , -0.472],
        [-0.   ,  0.472],
        [-0.   , -0.472]],

       [[ 0.   ,  0.708],
        [ 0.   , -0.708],
        [-0.   ,  0.708],
        [-0.   , -0.708]],

       [[ 0.   ,  0.944],
        [ 0.   , -0.944],
        [-0.   ,  0.944],
        [-0.   , -0.944]],

       [[ 0.236,  0.   ],
        [ 0.236, -0.   ],
        [-0.236,  0.   ],
        [-0.236, -0.   ]],

       [[ 0.236,  0.236],
        [ 0.236, -0.236],
        [-0.236,  0.236],
        [-0.236, -0.236]],

       [[ 0.236,  0.472],
        [ 0.236, -0.472],
        [-0.236,  0.472],
        [-0.236, -0.472]],

       [[ 0.236,  0.708],
        [ 0.236, -0.708],
        [-0.236,  0.708],
        [-0.236, -0.708]],

       [[ 0.472,  0.   ],
        [ 0.472, -0.   ],
        [-0.472,  0.   ],
        [-0.472, -0.   ]],

       [[ 0.472,  0.236],
        [ 0.472, -0.236],
        [-0.472,  0.236],
        [-0.472, -0.236]],

       [[ 0.472,  0.472],
        [ 0.472, -0.472],
        [-0.472,  0.472],
        [-0.472, -0.472]],

       [[ 0.472,  0.708],
        [ 0.472, -0.708],
        [-0.472,  0.708],
        [-0.472, -0.708]],

       [[ 0.708,  0.   ],
        [ 0.708, -0.   ],
        [-0.708,  0.   ],
        [-0.708, -0.   ]],

       [[ 0.708,  0.236],
        [ 0.708, -0.236],
        [-0.708,  0.236],
        [-0.708, -0.236]],

       [[ 0.708,  0.472],
        [ 0.708, -0.472],
        [-0.708,  0.472],
        [-0.708, -0.472]],

       [[ 0.944,  0.   ],
        [ 0.944, -0.   ],
        [-0.944,  0.   ],
        [-0.944, -0.   ]]])

答案 1 :(得分:0)

我的结论是,除了首先通过列表之外,没有更简单的方法将集合转换为数组。

就我的具体情况而言,我最终使用了以下内容:

rad = 0.944
n = 5
pairs = np.array([item for item in itertools.product(np.linspace(-rad, rad, 2*n-1), repeat=2) if math.hypot(item[0], item[1]) <= rad])

答案 2 :(得分:-1)

您可以使用np.fromiter直接从chain.from_iterable的生成器输出构建数组,并使用np.unique删除重复数据:

pairs = np.unique(np.fromiter(itertools.chain.from_iterable(data), dtype=float))

请注意,dtype函数的np.fromiter参数是必需的。