Creating an numpy array from a list for using with NumPyArrayToTable

2418
7
Jump to solution
10-26-2014 01:27 AM
JanetRogers
Occasional Contributor II

I am attempting to put a 2-dimensional list of data into a numpy array for use with NumPyArrayToTable.  If I create a array of strings like this:

inarray = numpy.array( [ ('Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0')

('Route.mxd', 'False', 'World Cities', 'cities', '50.0')

('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0')

('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0')],numpy.dtype(dts))

Then it converts perfectly into a numpy.array and then to an ArcGIS Table. The data-type string works perfectly:

[('Map', '|S45'), ('RelativePath', '|S5'), ('LayerName', '|S35'), ('LayerFile', '|S85'), ('Scale', '|S15')]

However when I create an list via looping and appending the strings in python (code below), I end up with an list/array like this:

[ ['Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'],

['Route.mxd', 'False', 'World Cities', 'cities', '50.0'],

['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'],

['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0']]

This converts to a numpy.array with no problems, but when I use NumPyArrayToTable, it creates the 5 columns correctly, but puts all the data in the first column as:

Route.mxd

False

Emirates_Route

route.shp

0.0

Route.mxd

False

World Cities...

I can see that these two data structures are being handled differently by numpy, however I don't know how to get the second into the same format as the first, which works perfectly.  I have tried using asarray to convert the list to an array but this appears to duplicate everything and still leaves the square brackets.

(I realise that numpy is not really meant for strings, but I am trying to code using it and this is just a theoretical exercise.)

MyList.append([])                                              MyList[count].append(mapDoc.encode('UTF8'))                         MyList[count].append(relPaths.encode('UTF8'))                         MyList[count].append(lyrTitle.encode('UTF8'))                        MyList[count].append(sourceTitle.encode('UTF8'))                         MyList[count].append(theScale.encode('UTF8'))

0 Kudos
1 Solution

Accepted Solutions
DanPatterson_Retired
MVP Emeritus

I had something along the line that numpy doesn't play nice with lists of lists but lists of tuples are fine.  I am not sure what you want exactly since I don't want to crank up arcmap to test, but have a look at this done in the commandline  ... hopefully it will give you an array to use as a table.

>>> a =[ ['Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'],['Route.mxd', 'False', 'World Cities', 'cities', '50.0'],
         ['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'],['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0']]
>>> a
[['Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'], ['Route.mxd', 'False', 'World Cities', 'cities', '50.0'],
 ['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'], ['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0']]
>>> import numpy as np
>>> b = []
>>> for i in a:
...  b.append(tuple(i))
... 
>>> b
[('Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'), ('Route.mxd', 'False', 'World Cities', 'cities', '50.0'),
 ('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'), ('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0')]
>>> dtype=[('Map', '|S45'), ('RelativePath', '|S5'), ('LayerName', '|S35'), ('LayerFile', '|S85'), ('Scale', '|S15')]
>>> dtype
[('Map', '|S45'), ('RelativePath', '|S5'), ('LayerName', '|S35'), ('LayerFile', '|S85'), ('Scale', '|S15')]
>>> c = np.array(b,dtype)
>>> c
array([('Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'),
       ('Route.mxd', 'False', 'World Cities', 'cities', '50.0'),
       ('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'),
       ('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0')],
      dtype=[('Map', 'S45'), ('RelativePath', 'S5'), ('LayerName', 'S35'), ('LayerFile', 'S85'), ('Scale', 'S15')])
>>>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

To which I should add, you can now call by fieldname

>>> c['Map']
array(['Route.mxd', 'Route.mxd', 'Updated.mxd', 'Updated.mxd'], 
      dtype='|S45')
>>> c['RelativePath']
array(['False', 'False', 'True', 'True'], 
      dtype='|S5')
>>> c['LayerName']
array(['Emirates_Route', 'World Cities', 'Meter1', 'Meter1'], 
      dtype='|S35')
>>> c['LayerFile']
array(['route.shp', 'cities', 'Meter1', 'Meter1'], 
      dtype='|S85')
>>> c['Scale']
array(['0.0', '50.0', '0.0', '0.0'], 
      dtype='|S15')
>>>

 

View solution in original post

0 Kudos
7 Replies
DanPatterson_Retired
MVP Emeritus

I had something along the line that numpy doesn't play nice with lists of lists but lists of tuples are fine.  I am not sure what you want exactly since I don't want to crank up arcmap to test, but have a look at this done in the commandline  ... hopefully it will give you an array to use as a table.

>>> a =[ ['Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'],['Route.mxd', 'False', 'World Cities', 'cities', '50.0'],
         ['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'],['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0']]
>>> a
[['Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'], ['Route.mxd', 'False', 'World Cities', 'cities', '50.0'],
 ['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'], ['Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0']]
>>> import numpy as np
>>> b = []
>>> for i in a:
...  b.append(tuple(i))
... 
>>> b
[('Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'), ('Route.mxd', 'False', 'World Cities', 'cities', '50.0'),
 ('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'), ('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0')]
>>> dtype=[('Map', '|S45'), ('RelativePath', '|S5'), ('LayerName', '|S35'), ('LayerFile', '|S85'), ('Scale', '|S15')]
>>> dtype
[('Map', '|S45'), ('RelativePath', '|S5'), ('LayerName', '|S35'), ('LayerFile', '|S85'), ('Scale', '|S15')]
>>> c = np.array(b,dtype)
>>> c
array([('Route.mxd', 'False', 'Emirates_Route', 'route.shp', '0.0'),
       ('Route.mxd', 'False', 'World Cities', 'cities', '50.0'),
       ('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0'),
       ('Updated.mxd', 'True', 'Meter1', 'Meter1', '0.0')],
      dtype=[('Map', 'S45'), ('RelativePath', 'S5'), ('LayerName', 'S35'), ('LayerFile', 'S85'), ('Scale', 'S15')])
>>>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

To which I should add, you can now call by fieldname

>>> c['Map']
array(['Route.mxd', 'Route.mxd', 'Updated.mxd', 'Updated.mxd'], 
      dtype='|S45')
>>> c['RelativePath']
array(['False', 'False', 'True', 'True'], 
      dtype='|S5')
>>> c['LayerName']
array(['Emirates_Route', 'World Cities', 'Meter1', 'Meter1'], 
      dtype='|S35')
>>> c['LayerFile']
array(['route.shp', 'cities', 'Meter1', 'Meter1'], 
      dtype='|S85')
>>> c['Scale']
array(['0.0', '50.0', '0.0', '0.0'], 
      dtype='|S15')
>>>

 

0 Kudos
JanetRogers
Occasional Contributor II

That looks really promising Dan.  Will give it a try when I get to work in the morning,.

Janet

0 Kudos
DanPatterson_Retired
MVP Emeritus

As a tip, Janet, I keep a text file full of useful numpy stuff including type cases so I don't forget them and have to search all over the place or re-invent the wheel

0 Kudos
JanetRogers
Occasional Contributor II

Great, Dan, that works perfectly.  And I can see why you keep a text file on hand.  I  thought  I was looking at tuples but I didn't think that it would be reasonable.  Apparently it was.  That has been a bit help in getting through the code I was stuck on.  I can now use this to list the properties of feature classes in a folder of MXDs to a table with mimimal lines of code.  Thank you.

0 Kudos
DanPatterson_Retired
MVP Emeritus

https://community.esri.com/docs/DOC-2289?sr=search&searchId=3c7390db-66ec-43a2-a1db-4605893a4946&sea...Janet have a look of my project in progress mxd info  to see if there is anything worth stealing from there.  I took a different tact, but I could provide you with a testable version if you find anything useful.  Currently it is restricted to just reading, but that can be changed.

0 Kudos
JanetRogers
Occasional Contributor II

Hi Dan,

My attempt to join your group was rejected.  I have just sent another request, if you wouldn't mind letting me in.

0 Kudos
DanPatterson_Retired
MVP Emeritus

Janet, most content has been moved, but it could be used for further testing if you wish.  I use it mostly as a staging ground for current projects so generally it is restricted.


Janet Rogers   I just uploaded the last versions of the *.tbx, documentation etc

0 Kudos