Looping through table to calculate separations - Python
<p>Okay so I have a table of xy coordinates for a bunch of different points like this:</p>

<blockquote>
<pre><code>   ID      X          Y
     1    403.294    111.401
     2   1771.424     62.183
     3    804.812     71.674
     4    2066.54     43.456
     5    2208.55     40.907
</code></pre>
</blockquote>

<p>Each row represents an object with its ID, X, and Y listed. In reality, my table contains about 1345 rows. What I'm trying to do is loop through each row and calculate the separation of that object from all other objects in the table which I'll eventually use to make a histogram. What I have so far is: </p>

<pre><code>sep_dat = np.zeros(shape=(5,5))               #create array for writing into
dat = np.loadtxt('SEA_mini_test.tab')         #table of data
IDs = dat[:,0]
X_dat = dat[:,1]
X_dat = np.sort(X_dat)
Y_dat = dat[:,2]
Y_dat = np.sort(Y_dat)
for i, x, y in zip(xrange(len(X_dat)), X_dat, Y_dat):
  sep_dat[i] = math.sqrt((x-X_dat)**2+(y-Y_dat)**2)
  np.savetxt('SEA_mini_seps.dat', sep_dat, fmt='%10.9f')
</code></pre>

<p>But I have yet to get it to run successfully. The last error I got was: </p>

<blockquote>
  <p>TypeError: only length-1 arrays can be converted to Python scalars</p>
</blockquote>

<p>So how can I get this to run properly? </p>

<p>And how could I get it to ignore itself when its doing the calculations? Like for object 1 (row 1) I don't want it to calculate the separation from itself. I tried adding the IDs into zip and adding an if statement inside the for loop before the calculation like  <code>if id != id:</code> but that wouldn't work. Does anyone have an idea on how I could do this?</p>

<p>And another question I had was, how could I write all the data into a flattened array? Right now, I have it create an empty array of zeros that I write over with the calculated values, but in the end I get a (5,5) array. But I want a (5,1) so that I can plot it as a histogram. Any ideas?</p>

<p>The error occurs because math.sqrt() can only take a float value, if you pass an np.array it will attempt to convert to a float.  This only works if the array contains a single value.</p>

<pre><code>&gt; math.sqrt(np.array([2]))
1.4142135623730951

&gt; math.sqrt(np.array([2,1])) Traceback (most recent call last):

  File "&lt;ipython-input-49-f9a9c77bfbdf&gt;", line 1, in &lt;module&gt;
    math.sqrt(np.array([2,1]))

TypeError: only length-1 arrays can be converted to Python scalars
</code></pre>

<p>You can use np.sqrt() which will return an array of square roots.</p>

<pre><code>&gt; x = np.arange(1,5)     #[1,2,3,4]
&gt; y = x[::-1]            #[4,3,2,1]
&gt; z = x**2 + y**2        #[1*1+4*4,...,4*4+1*1]
&gt; np.sqrt(z)
array([ 4.12310563,  3.60555128,  3.60555128,  4.12310563])
</code></pre>

<p>If this is the desired behaviour</p>

python loops numpy