How do I populate an attribute field with the number of selected records?

3027
39
Jump to solution
09-23-2013 08:07 AM
TysonBarlow
New Contributor III
I'm working with two datasets:
1) School Boundaries (polygons)
2) Students (points)


In the school boundary dataset I have fields for each grade (Grade1, Grade2, etc...) and would like to populate those fields with the number of students for each respective grade in each school boundary. The Students dataset has a field that contains each student's grade.

I have been doing it manually, but figure there should be a way to automate this process. Any help is appreciated, and if I haven't explained myself well enough, please let me know.

Thanks!
Tags (2)
0 Kudos
39 Replies
TysonBarlow
New Contributor III
I was writing my last response while you posted your last one. I'll see what I can do with what you gave me there. I think i'm gettin gclose!  I'll let you know...
0 Kudos
T__WayneWhitley
Frequent Contributor
EDIT:
PLEASE SKIP DOWN TO POST #39 FOR THE MODIFIED TESTED SCRIPT AND EXPLANATION (starts with "OK -- it's a new day...")
My apologies for posting faulty code without fully testing...this post may be deleted later (by me or a moderator) if it's determined not to contain enough relevant info to keep.  Late in the day and couldn't see the forest for the trees, so to speak- sorry.

OK, based on what you said about the preschool values and to minimize confusion, I suggest the following - to change an 'else' statement to an 'elif' statement.  All that changes is to execute a further query condition rather than to 'lump' whatever remains together.

So based on that, locate this block of code below (it is in the code twice; the 2nd execution of this is to catch the final value iteration) - at any rate it needs to be modified in both places:
if not compareVal in ['KA', 'KP', 'PA', 'PP']:
     fieldName = 'Grade_' + str(int(compareVal))
else:
     fieldName = 'Grade_K'
     count += row.getValue(fieldName)


...locate within this the 'else' line, and change it accordingly to the 'elif' line below:
if not compareVal in ['KA', 'KP', 'PA', 'PP']:
     fieldName = 'Grade_' + str(int(compareVal))
elif not compareVal in ['PA', 'PP']:
     fieldName = 'Grade_K'
     count += row.getValue(fieldName)


Remember to change it in both places...
To explain a little further, what the elif does in this case is further filter out the P values (so that it isn't included in the count for K)...this is a little bit sloppy, but minimizes the modifications you have to do.  I really did not test this, but what should happen then is that the P vals are left 'uncounted', so to speak.  They aren't included at all...please note that if you actually have any coded by 'P' explicitly (you left that out before), then you can add that into the list in similar fashion.

Let me know if this works ok for now - that should work adequately enough for your purposes, I think, to load the code -- and probably later you can refine this yourself into a script tool.  (Probably not relevant to this thread)

Enjoy,
Wayne
0 Kudos
TysonBarlow
New Contributor III
I saved your .shp that you executed the code for, saved a copy to my desktop, then made all grade values in the grade fields 0. I called the new coped shapefile schoolJoinToPolys5.shp

I imported arcpy, then set the shapefile to the new one on my desktop (I hope I did that right).  I then loaded your .py file from the last response and ran the script. I've pasted exactly what it looks like from my Python window in ArcMap. I get a runtime error saying that the name outField is not defined.

The image I put in the next post has a screenshot of what I tried.
0 Kudos
TysonBarlow
New Contributor III
Maybe this'll help? A screenshot of what I tried...


[ATTACH=CONFIG]27824[/ATTACH]
0 Kudos
T__WayneWhitley
Frequent Contributor
...oops, outField is now a variable representing your output field you defined and mapped from the spatial join...

So you need to define it before you load the rest, that would've been step 3 after defining shp, so for me it would have been:

outField = 'outGrades'


However, looks like there's another error with this line:
outGrades = row.outGrades.split(',')

...needs to be changed to:
outGrades = row.getValue(outField).split(',')


OK?  Also, if you run across any other var references that are not set, you will get a similar error.  Almost there!  Another thing that may prove to be troublesome is indention - easy to foul this up copying/pasting blocks of code, so avoid that at this juncture if possible and instead, with the minimal changes you need to apply, try typing it directly.
0 Kudos
TysonBarlow
New Contributor III
It worked with the sample shapefile! You're awesome! I work mostly with feature classes, so now i'll see if I can get it to work on that. Thank you soooo much!
0 Kudos
T__WayneWhitley
Frequent Contributor
OK, that is great Tyson!
Yeah, I usually work with feature classes too rather than shapefiles...but keep in mind, you will probably need to change your 'filter' query on the cursor to IS NOT NULL, that or simply do not include in the spatial join output ALL RECORDS - I think there's an option for excluding polys with no point to join.  Just get the filter right and you won't have to worry about it.

If you're confident you can continue on your own, and satisfied I have answered your question, please mark the post you deem best answers your question (the green checkmark).  I usually don't ask that, but since the thread is a little long, it could help other users if you 'approve' one of the answers.  ...and, ok, I could use an additional pat on the back, lol!  Interesting problem, thank you - I reiterate that this is a 'classic' type of GIS problem, with an additional field mapping summary 'twist'.

Later, when you wish to create a script tool, you can read up on the web help - you can create tool parameters out of the input fc (get parameter as text) and the output field and you can if you wish script the spatial join.  Optionally, you can write it (if so inclined) to bypass using the Spatial Join tool, but that is for another day.  Good to know you have options.

Enjoy,
Wayne
0 Kudos
TysonBarlow
New Contributor III
When I try to run it with my feature class, this is what I get. I know you posted something earlier that suggested what this was all about, but it fills in the grades for about 8 records when I run it like this.
[ATTACH=CONFIG]27828[/ATTACH]
0 Kudos
T__WayneWhitley
Frequent Contributor
Yes, change this line:
query = arcpy.AddFieldDelimiters(shp, 'outGrades') + ' NOT IN (\' \')'


...to this:
query = arcpy.AddFieldDelimiters(shp, 'outGrades') + ' IS NOT NULL'


NOTE:  Except if you've made a variable reference to your spatial join output field name, then:

query = arcpy.AddFieldDelimiters(shp, outField) + ' IS NOT NULL'


Does that make better sense?
0 Kudos
TysonBarlow
New Contributor III
You're unbelievable! I cannot thank you enough! This will save me so much time in the future!

EDIT: All of the fields seem to be calculating correctly except for the Grade_K field. One thing I noticed that the sample students file i've shared did not have students whose grade=K. We do have a small number of those students (around 10). That, I don't think is the issue though, because the grade_k totals are off by weird amounts (some by 30+, some by 2).
0 Kudos