0

I have a column X in attribute table where the values are repeated in some lines. What I need is to make a condition that says: when the values in column X are the same, find the minimum of column Y and write it in a new column.

My attribute table is something like this:

enter image description here

My knowledge in python is very limited. I'm trying the code below but it's not working, has a syntax error, and if I put "if" instead of "elif" it works but results 0 in all lines, and what I want is to write "Y" or "0" in each line.

def func (code,w,ataq):
 Y=w*ataq

 if X == 0:
     return 0
 else: 
     if X == X + 1:
      m=min(Y)
      elif Y == m:
          return Y
     else:
         return 0

The problem is in the incrementation of X. How can I do this differently?

UPDATE Now I'm trying this code on python window:

import arcpy
featureClass="C:\\Users\\andreia.medeiros\\Documents\\ArcGIS\\Trabalho\\Modelo\\linhas_150_5km.shp"
data=arcpy.SearchCursor("linhas_150_5km","","","Line_code;w_min;ang_ataque","Line_code;w_min;ang_ataque")
import collections
d=collections.defaultdict(list)

for Line_code,w_min,ang_ataque in data:
    d[Line_code].append(w_min*ang_ataque)

But there's something wrong with "data". When I print "data" it shows "geoprocessing cursor object object at 0x1DAED2A0" And I have a TypeError: 'Row' object is not iterable

Any help to figure it out what is wrong here?

  • How can code ever equal code plus one? you'll always get zero surely? the syntax error is be cause you've but an elif in the "do something" part of the if statement, you need an action THEN the elif, but maybe you just don't need the elif - its not clear what you're trying to do there... – whatahitson Sep 15 '15 at 12:24
  • How is your question related to GIS? where do you try your code (Field Calculator)? Your question seems to be off-topic here! – Farid Cheraghi Sep 15 '15 at 12:47
  • I'm doing this on Field Calculator using data from 3 columns from an attribute table. Is it not related to GIS? – AndM Sep 15 '15 at 12:50
  • Your code and process is confusing. I am sure this can be coded with arcpy, but without knowing what exactly you're doing or want done, it is hard to really pick the right direction to go. Are you saying that some successive records have the same X field and in that case, you want to find the overall minimum value of the Y field and place it into another column (e.g. Z field)? Like (in pseudocode), if currentX = nextX: Z = minimum(Y)?.. – Branco Sep 15 '15 at 13:46
  • Yes. For example in the first 3 lines I have the same X, so in column Z i want to rewrite the minimum Y of that 3 lines, in that case is 1,2. In the line above and in the line below i just want to write 0 in Z column. Let me know if I wasn't clear... – AndM Sep 15 '15 at 13:51
1

With collections.defaultdict, this is a quite straightforward task. Let's say that this is our arcmap attribute table. It does not matter if x_field is sequential or in any type of order. I've denoted the minimum values for ease:

C   51
E   75
E   27 <----
C   28 <----
B   35
C   94
D   89
C   68
A   25 <----
B   8  <----
A   60
A   34
E   92
A   54
D   76 <----

As @artwork21 pointed out, you can use cursors to read this data into a python list of lists:

data = [row for row in arcpy.da.SearchCursor(FC, [x_field, y_field])]
#For this example.....
data = [['C', 51], ['E', 75], ['E', 27], ['C', 28], ['B', 35], ['C', 94], ['D', 89], ['C', 68], ['A', 25], ['B', 8], ['A', 60], ['A', 34], ['E', 92], ['A', 54], ['D', 76]]

From here, we'll create a dictionary for each unique value in x_field (this is actually an example from the help docs:

import collections
ddict = collections.defaultdict(list)
for x,y in data:
   ddict[x].append(y)
#ddict.items() displays [('A', [25, 60, 34, 54]), ('C', [51, 28, 94, 68]), ('B', [35, 8]), ('E', [75, 27, 92]), ('D', [89, 76])]

Getting the minimum values is now simple:

minvals = dict((key, min(ddict[key])) for key in ddict.keys())
#minvals displays {'A': 25, 'C': 28, 'B': 8, 'E': 27, 'D': 76}

You can then use an update cursor to write the new values back to the attribute table's z_field:

with arcpy.da.UpdateCursor(FC [x_field, z_field]) as rows:
    for row in rows:
        row[1] = minvals[row[0]]
0

I would suggest to perform this in arcpy/python script, not in field calculator. The code flow would go something like this:

  1. Use search cursor to iterate through table
  2. Store current x field value in a variable
  3. Within search cursor use select layer by attribute on x field/#2 variable
  4. Next, create a list variable and add all selected y values to it
  5. Use min method on list and write value to a new variable
  6. Embed another update cursor after step 5 within the search cursor and use conditional logic to find the record that equal step/variable #2 and #5 and update z field value

The one area I'm unsure of is how you plan to find the MIN of selected y field values, are those commas supposed to be periods?

  • This is to put in a model, in modelbuilder, how can I "merge" all that process? – AndM Sep 15 '15 at 14:01
  • No, within python window in ArcMap or ArcCatalog. – artwork21 Sep 15 '15 at 14:27
  • I'm sorry, what I wanted to say is that I will use this in a model, in modelbuider. That's why I was doing this code on Calculate Field tool. Doing it on python window how can I put it into modelbuilder? – AndM Sep 15 '15 at 14:31
  • 1
    You can create a script, add the script to your tool box, and then add the script to your model. – KJYDavis Sep 15 '15 at 14:42
  • Thanks for your help, but I have 0 experience working in python window, using cursors and all of that. I'll try – AndM Sep 15 '15 at 15:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.