[GRASS-dev] Write array to (point) attribute table
Paulo van Breugel
p.vanbreugel at gmail.com
Thu Oct 1 08:28:22 PDT 2015
On 01-10-15 09:15, Moritz Lennert wrote:
> On 01/10/15 00:05, Paulo van Breugel wrote:
>>
>>
>> On 30-09-15 17:52, Paulo van Breugel wrote:
>>>
>>>
>>> On 30-09-15 17:47, Anna Petrášová wrote:
>>>>
>>>>
>>>> On Wed, Sep 30, 2015 at 11:20 AM, Paulo van Breugel
>>>> <p.vanbreugel at gmail.com> wrote:
>>>>
>>>>
>>>>
>>>> On 30-09-15 16:18, Anna Petrášová wrote:
>>>>>
>>>>>
>>>>> On Wed, Sep 30, 2015 at 9:27 AM, Paulo van Breugel
>>>>> <p.vanbreugel at gmail.com <mailto:p.vanbreugel at gmail.com>> wrote:
>>>>>
>>>>>
>>>>>
>>>>> On Wed, Sep 30, 2015 at 11:53 AM, Pietro
>>>>> <peter.zamb at gmail.com> wrote:
>>>>>
>>>>> On Wed, Sep 30, 2015 at 9:51 AM, Paulo van Breugel
>>>>> <p.vanbreugel at gmail.com> wrote:
>>>>> >
>>>>> >
>>>>> > On Wed, Sep 30, 2015 at 2:02 AM, Anna Petrášová
>>>>> <kratochanna at gmail.com>
>>>>> > wrote:
>>>>> >>
>>>>> >>
>>>>> >>
>>>>> >> On Tue, Sep 29, 2015 at 6:09 PM, Paulo van Breugel
>>>>> >> <p.vanbreugel at gmail.com> wrote:
>>>>> >>>
>>>>> >>> This must be a very basic question, but I can't find
>>>>> an easy/direct way
>>>>> >>> to do this. In python, if I have an array with
>>>>> values with a length equal to
>>>>> >>> the number of rows in an attribute table of a
>>>>> (point) vector layer, how can
>>>>> >>> I write those values to a new column in that
>>>>> attribute table. I can of
>>>>> >>> course first create the column, but than how to
>>>>> update that column with the
>>>>> >>> values in the array?
>>>>> >>
>>>>> >>
>>>>> >> it should be pretty easy to do with pygrass,
>>>>> unfortunately there is no
>>>>> >> example on assigning attributes in the official
>>>>> documentation [1], but it
>>>>> >> should be pretty easy, something like that (not
>>>>> tested):
>>>>> >>
>>>>> >> with VectorTopo('myvector', mode='w') as vectormap:
>>>>> >> for feature in vectormap:
>>>>> >> feature.attrs['mycolumn'] = value
>>>>> >>
>>>>> >>
>>>>> > Thanks, but that seems to write the vector back
>>>>> without attribute table
>>>>>
>>>>> You have to save the changes in the database out from
>>>>> your cycle, with:
>>>>>
>>>>> vectormap.table.conn.commit()
>>>>>
>>>>>
>>>>> Thanks Pietro. I am, however, not sure I understand (I tried
>>>>> to use it, but thanks to my limited experience in Python /
>>>>> pygrass not much luck). Just to be more specific, I am
>>>>> trying to create a script that divides points in training
>>>>> and test groups, similar to v.kcv, but with points clustered
>>>>> in space. E.g.,
>>>>>
>>>>> # Create vector
>>>>> grass.run_command("v.random", output="testB", npoints=10,
>>>>> overwrite=True)
>>>>> grass.run_command("v.db.addtable", map="testB", columns="X
>>>>> DOUBLE PRECISION,Y DOUBLE PRECISION,GR INTEGER")
>>>>> grass.run_command("v.to.db", map="test", option="coor",
>>>>> columns="X,Y")
>>>>>
>>>>> # Create groups
>>>>> vectmap = 'test'
>>>>> cvals = array(grass.vector_db_select(vectmap, layer =
>>>>> int(1), columns = 'X,Y')['values'].values()).astype(np.float)
>>>>> centroids,_ = kmeans(cvals,2)
>>>>> idx,_ = vq(cvals,centroids)
>>>>>
>>>>> # write results to tabel
>>>>> Now I would like to write idx to the column 'GR' in the
>>>>> attribute table of 'test'.
>>>>>
>>>>> p.s. I am first creating the XY columns now, but is there a
>>>>> function to get the coordinates (cvals) in pygrass directly?
>>>>>
>>>>>
>>>>> I don't fully understand the example,
>>>>
>>>> Thanks for the quick response. I basically have a list with
>>>> values (idx in the example above) which I like to add as a column
>>>> to the attribute table of an existing vector (point layer). The
>>>> length of idx is equal to the number of rows in the attribute
>>>> table. The solution of Anna seems like an elegant solution (and
>>>> easier and more flexible than other solutions I tried using e.g.,
>>>> sqlite3). However, as I wrote, I end up with a vector without
>>>> attribute table. You wrote that I "have to save the changes in
>>>> the database out from your cycle, with:
>>>> vectormap.table.conn.commit()". I am, however, not sure what you
>>>> mean with 'out from your cycle' or how to implement that.
>>>>
>>>>
>>>> probably after the for cycle ends you would call this
>>>> 'vectormap.table.conn.commit()', if it doesn't works, try to put it
>>>> in the cycle (I am not sure what is supposed to work).
>>>
>>> I did try both, with no luck so-far. I'll give it another try though,
>>> perhaps I did something else wrong.
>>
>> Tried out again, but after running the code below, I end up with an
>> empty vector layer (no points and no attribute table). Same if I put the
>> vectormap.table.conn.commit() in the for cycle.
>>
>> import grass.script as grass
>>
>> from grass.pygrass.vector import VectorTopo
>>
>> grass.run_command("v.random", output="testB", npoints=10,
>> overwrite=True)
>>
>> grass.run_command("v.db.addtable", map="testB", columns="GR INTEGER")
>>
>> with VectorTopo('testB', mode='w') as vectormap:
>>
>> for feature in vectormap:
>>
>> feature.attrs['GR'] = 9
>>
>> vectormap.table.conn.commit()
>
>
> Just a wild guess, here without looking at the library code, but could
> it be that it should be
>
> VectorTopo('testB', mode='a')
>
> instead of
>
> VectorTopo('testB', mode='w')
That is not a valid option; "Mode not supported. Use one of: 'r', 'rw',
'w' ". This did make me try again though, but now with mode='rw', which
worked:
idx= array([0, 1, 0, 0, 0, 0, 1, 1, 0, 1])
i = -1
with VectorTopo('testB', mode='rw') as vectormap:
for feature in vectormap:
i = i + 1
feature.attrs['GR'] = idx[i]
vectormap.table.conn.commit()
Thanks all for the help/advices
> Moritz
More information about the grass-dev
mailing list