简体   繁体   English

如何在python中从一个集转换为一个数组

[英]How to convert from a set to an array in python

The question: 问题:

I need to convert a set to an array. 我需要将一个集转换为数组。 If I try to just do np.array(X), I get an array that contains a set, which isn't very helpful. 如果我尝试只做np.array(X),我得到一个包含一个集合的数组,这不是很有用。 If I convert my set to a list and then my list to an array, everything works fine, but that seems needlessly complex (the line of code in question is a convoluted mess of needless complexity already). 如果我将我的集合转换为列表然后将我的列表转换为数组,一切正常,但这看起来不必要复杂(所讨论的代码行已经是一个复杂的不必要的复杂性)。 Is there a way to go straight from set to array? 有没有办法直接从一个阵列到阵列?


Code context, if helpful: 代码上下文,如果有帮助:

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))))

The point of the set is to remove duplicates from the chain. 该集的要点是从链中删除重复项。 I know there are ways of doing this with an array, but it doesn't seem possible to convert an itertools.chain object directly into an array either. 我知道有一些方法可以使用数组执行此操作,但似乎无法将itertools.chain对象直接转换为数组。

Holistically, this code just models a circle using a uniform distribution of x,y points, and speeds up the process by evoking symmetry between the four quadrants. 从整体上看,这段代码只是使用x,y点的均匀分布来模拟圆形,并通过唤起四个象限之间的对称来加速过程。

Here is a pure Numpythonic approach: 这是一个纯粹的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

Note that if you make sure that there is no duplicate item in your linspace array there won't be any one in the total combinations. 请注意,如果确保linspace阵列中没有重复项,则总组合中将不存在任何项。

And here is the total result: 以下是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.   ]]])

My conclusion is that there is no easier way to convert a set to an array other than going through a list first. 我的结论是,除了首先通过列表之外,没有更简单的方法将集合转换为数组。

In terms of my particular situation, I ended up using the following: 就我的具体情况而言,我最终使用了以下内容:

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])

You can use np.fromiter to construct an array directly from the generator output of chain.from_iterable , and np.unique to remove duplicates: 您可以使用np.fromiter直接从chain.from_iterablenp.unique的生成器输出构造数组,以删除重复项:

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

Note that the dtype argument of the np.fromiter function is required. 需要注意的是dtype中的参数np.fromiter功能是必需的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM