2014-11-25 85 views
0

我有一个包含圆的所有半径的列表,我试图用对角半径计算圆的直径。Numpy:添加圆的半径以形成直径

我的例子功能如下:

radii=[2.1, 2.4, 2.3, 2.2, 2.0, 2.2, 2.5, 2.1] 

def dia(radius): 
    Diameter = [] 
    for i in range(int(len(radii)/2)): 
     print i 
     Diameter.append(radii[i]+radii[int(len(radii)/2+i)]) 
    print Diameter 

dia(radii) 

现在,这适用于相对较小的数据集。但是,每当我有一个圈可以说100个半径,我有大约10万个圈子。这个功能变得非常慢,并且运行它们需要很长的时间。我想知道如何用numpy或任何python工具来加速它。任何人有想法?

+1

你是否在使用传统定义的“radii”和“diameter”? – will 2014-11-25 01:46:22

+0

是:)直径只是2 *半径,但在这种情况下将是对角半径。 – Arbitel 2014-11-25 01:49:17

+0

什么是“对角半径”? – will 2014-11-25 01:49:38

回答

2

井与NumPy你可以简单地做这样:

>>> radii = np.array([2.1, 2.4, 2.3, 2.2, 2.0, 2.2, 2.5, 2.1]) 
>>> radii[:len(radii)/2] + radii[len(radii)/2:] 
array([ 4.1, 4.6, 4.8, 4.3]) 

这是相当快于你的代码清单理解基于Python版本。

>>> radii = [2.1, 2.4, 2.3, 2.2, 2.0, 2.2, 2.5, 2.1]*10**6 
>>> radii_a = np.array(radii) 
>>> %timeit [radii[i]+radii[int(len(radii)/2+i)] for i in xrange(int(len(radii)/2))] 
1 loops, best of 3: 806 ms per loop 
>>> %timeit radii_a[:len(radii)/2] + radii_a[len(radii)/2:] 
100 loops, best of 3: 11.2 ms per loop 

注意,Python代码是因为如此多的全球查找每一次发生了len()的速度太慢,int()(是的,我们可以删除在Python 2 int()电话)等:

>>> %timeit le = int(len(radii)/2); [radii[i]+radii[le+i] for i in xrange(le)] 
1 loops, best of 3: 300 ms per loop 
+0

感谢python大师,这些都是我需要的答案。 Numpy真棒:) – Arbitel 2014-11-25 15:58:07

2

这是相当简单与numpy的:

radii=np.array([2.1, 2.4, 2.3, 2.2, 2.0, 2.2, 2.5, 2.1]) 
diameters = radii[:radii.size/2] + radii[radii.size/2:] 
+0

谢谢ebarr!这真的很直接,让我看起来很笨! – Arbitel 2014-11-25 15:58:32

1

首先,Ashwini Chaudharyebarr都EXPL艾因,你可以从一个Python环100米的半径内循环转换为NumPy的循环:

radii = np.array([2.1, 2.4, 2.3, 2.2, 2.0, 2.2, 2.5, 2.1]) 
radii[:len(radii)/2] + radii[len(radii)/2:] 

但是你可能还想考虑改变外环到NumPy的循环,通过使用二维数组,而不是阵列的列表:

circles = np.array([[2.1, 2.4, 2.3, 2.2, 2.0, 2.2, 2.5, 2.1], 
        [2.1, 2.4, 2.3, 2.2, 2.0, 2.2, 2.5, 2.1]]) 
circles[:,:circles.shape[1]/2] + circles[:,circles.shape[1]/2:] 

的时间为100米半径100K随机圈相比,我得到的只是更换内环,从更换两个一36.8x加速一个11.3倍的加速。所以,它不是很多的好处,但它仍然绝对值得做......当然,假设您可以将所有的圈子一次存储在内存中。

最后一句话似乎对这种可能性不屑一顾(你的评论意味着你以这种方式),但是要弄清楚我们在这里讨论的是多少内存。你有大约10万个圆圈,每个圆圈有100个半径,因此大约有10米半径。其中每个是float64,需要8个字节。再加上100个字节左右的数组头。这意味着我们正在谈论80MB以下。那是什么也没有。除非您希望将来处理至少一个数量级的数据,否则将所有内容放入二维阵列中的速度和便利性几乎肯定会取得胜利。

+0

谢谢abarnert,我意识到在这种情况下的内存是问题:) – Arbitel 2014-11-25 15:59:01

+0

@Arbitel:内存*真的是一个问题吗?我们在这里讨论80MB以下。 – abarnert 2014-11-25 19:22:40

+0

我在修改代码时犯了一个愚蠢的错误,我在做循环时将列表循环并冻结。我的错。 有没有一种方法来数组理解?我只想总和具有> 0值的半径。其中一些具有负面价值。如果半径[x]> 0],我可以做[半径[:len(半径)/ 2] +半径[len(半径)/ 2:]之类的东西吗? – Arbitel 2014-11-25 19:40:59