2

I'm trying to get a 2D array from a feature class using numpy and arcpy...

import arcpy
import numpy
locxyarray = arcpy.da.FeatureClassToNumPyArray("Points", ['SHAPE@XY', 'PrimeKey'])

The result:

array([([506173.7478, 5455684.263900001], 1),
       ([506175.22869999986, 5455648.723099999], 2),
       ([506229.03359999973, 5455661.5572999995], 3),
       ([506250.25939999986, 5455614.169500001], 4),
       ([506305.54509999976, 5455579.122300001], 5),
       ([506331.70710000023, 5455688.2129], 6)], 
      dtype=[('SHAPE@X', '<f8', (2,)), ('PrimeKey', '<i4')])

What I want:

array([(506173.7478, 5455684.263900001, 1),
       (506175.22869999986, 5455648.723099999, 2),
       (506229.03359999973, 5455661.5572999995, 3),
       (506250.25939999986, 5455614.169500001, 4),
       (506305.54509999976, 5455579.122300001, 5),
       (506331.70710000023, 5455688.2129, 6)], 
      dtype=[('SHAPE@XY', '<f8', (2,)), ('PrimeKey', '<i4')])

I want the above so I can sort by either the 0 or the 1 column, and return the 2 column in that order... Also, I need to be able to calculate the mean of X and the mean of Y, and pull all the Prime Keys with values above or below the mean.

EDIT - now able to make the array "look" correct;

locxyarray = arcpy.da.FeatureClassToNumPyArray("Points", ['SHAPE@X', 'SHAPE@Y', 'PrimeKey'])

>>array([(506173.7478, 5455684.263900001, 1),
       (506175.22869999986, 5455648.723099999, 2),
       (506229.03359999973, 5455661.5572999995, 3),
       (506250.25939999986, 5455614.169500001, 4),
       (506305.54509999976, 5455579.122300001, 5),
       (506331.70710000023, 5455688.2129, 6)], 
      dtype=[('SHAPE@X', '<f8'), ('SHAPE@Y', '<f8'), ('PrimeKey', '<i4')])

But I can't calculate the mean on the X or Y columns... (IndexError: too many indices)

SOLUTION (see comments below in solution, this is a summary):

import arcpy
import numpy as np
locxyarray = arcpy.da.FeatureClassToNumPyArray("Points", ['SHAPE@X','SHAPE@Y','PrimeKey'])
LSideLocs = np.where(locxyarray['SHAPE@X']<=np.mean(locxyarray['SHAPE@X']))
RSideLocs = np.where(locxyarray['SHAPE@X']>=np.mean(locxyarray['SHAPE@X']))

2
  • dtype in what you want can't be the same Commented Sep 19, 2014 at 18:09
  • @Cameron don't you want something like np.mean(x['SHAPE@X']) ? Commented Sep 22, 2014 at 21:20

2 Answers 2

2

You can play around with the name of field.

r=[(x['SHAPE@XY'][i][0],x['SHAPE@XY'][i][1],x['PrimeKey'][i]) for i in range(x.shape[0])]
x=np.rec.fromrecords(r, formats = 'f8,f8,i4', names = 'SHAPE@X,SHAPE@Y,PrimeKey')
rec.array([(506173.7478, 5455684.263900001, 1),
       (506175.22869999986, 5455648.723099999, 2),
       (506229.03359999973, 5455661.5572999995, 3),
       (506250.25939999986, 5455614.169500001, 4),
       (506305.54509999976, 5455579.122300001, 5),
       (506331.70710000023, 5455688.2129, 6)], 
      dtype=[('SHAPE@X', '<f8'), ('SHAPE@Y', '<f8'), ('PrimeKey', '<i4')])
Sign up to request clarification or add additional context in comments.

6 Comments

I was able to split out the SHAPE@X and SHAPE@Y directly in my call line... locxyarray = arcpy.da.FeatureClassToNumPyArray("Points", ['SHAPE@X', 'SHAPE@Y', 'PrimeKey']) But the resulting array still has too many indices to be able to calculate the mean of the X or Y column... (after that I want to pull the PrimeKeys of the rows above and below the mean to be able to split the table by X or Y)
I realised it was a bit too vague, so I tried to provide more detail above... essentially I need to be able to sort the array based on X and/or Y, and grab the corresponding PrimeKey's in the order I want (i.e. either from north to south, or east to west). I also need to be able to split the values in half (i.e. grab the east half, and order from north to south, then grab the west half, and order from north to south) I'm working to build labels that located regularly in layout space, but are leadered and orderd from north to south based on their data frame coordinates...
That looks promising... first I need the mean, then too be able to split the array between values above the mean and values below (i.e. split the labels between the right and left half of the page), then sorting based on Y would be perfect (let's me label from north to south). I'm struggling to make it work though... if I take you're suggestion of "np.mean(x['SHAPE@X'])" (or xmean = locxyarray.mean(x['SHAPE@X'])) then I get errors that it's an invalid index... If i try to argsort, I get an error that an integer is required...
@Cameropn have you tried this:np.mean(locxyarray['SHAPE@X'])? Do you get error with it?
@Cameron you can use np.where(locxyarray['SHAPE@X']<=np.mean(locxyarray['SHAPE@X'])) to again get the indices of elements less or equal to mean value.
|
0

Something like this:

>>> numpy.array([(x[0][0], x[0][1], x[1]) for x in locxyarray], dtype=np.dtype([('X', np.float), ('Y', np.float), ('PrimeKey', np.int32)]))
array([(506173.7478, 5455684.263900001, 1),
   (506175.22869999986, 5455648.723099999, 2),
   (506229.03359999973, 5455661.5572999995, 3),
   (506250.25939999986, 5455614.169500001, 4),
   (506305.54509999976, 5455579.122300001, 5),
   (506331.70710000023, 5455688.2129, 6)],
  dtype=[('X', '<f8'), ('Y', '<f8'), ('PrimeKey', '<i4')])

Note that dtype can't be kept the same because now the array elements consist of three fields instead of two in the original.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.