# How to recode and recalculate Field Values using ArcPy?

I am trying to figure out how to do several calculations through python and the arcpy set. I have an large dataset (7+ million records of individuals), and I am trying to code a value of 1 that denotes if the individuals are married.

Now I do not have marriage status, but I might be able to get it through following through this logic...

1. I have last name and address, I can create a new field that has this new identifier and determine if more than one person with the same last name lives at that address.
2. I have Age, so I could subtract the highest value from the second highest value to get the difference, and if that difference is say less than 15 years, assume they are married.
3. I do not have gender, but I do have first name. I have a large dataset of first names to determine gender, but there are too many names that are for both men and women, and I want to stay away from this as this process will be too involved.

So I can create the new field easy through update cursor. I dissolve it and join it back to the data set to get the number of people with eh same last name at an address. But after this, I am running into the my issues.

I would like to subtract the largest number that has the same id field, from the second highest number. But I am not sure how to write/code that in python to run it in ArcGIS. Is this even the best solution to solving this problem? I am welcome to all suggestions to help me get through this problem!!!!

• I think you're making some huge assumptions about peoples' marital status. Not every married couple share the same last name. Also, what if two people who are not married are at the same address such as brother and sister? – Fezter Oct 22 '13 at 4:07
• I am not trying to get 100% match, I am trying to collect as many as possible. I believe your examples would amount to maybe 10% of the total. Not looking for a commentary on my setup but rather how to accomplish it. – user23148 Oct 22 '13 at 11:31

Here's what I would try... since you have the age you can use that as a filter for determining whether or not they are "eligible" to be married... we'll use 18 and over...

• Create a string field named HASH
• Make the HASH field a combination of several other fields, like LAST_NAME + ADDRESS + CITY + STATE. I would write it something like this to get rid of all spaces and change everything to Upper case (NOTE: Only calculate the HASH field if the AGE field is >= 18...)

``````("".join(LAST_NAME.split()) + '-' + "".join(ADDRESS.split()) + '-' + "".join(CITY.split()) + '-' + "".join(STATE.split())).upper()
``````

Now you have HASH values for everyone 18 and up. Now you can use something like this...

``````import arcpy

fc = "C:/YourFileGeoDatabase.gdb/Dataset/YourFeatureClass"

where_clause = '"HASH"' + " <> ''"
sort_fields = "HASH A, FIRST_NAME A"

cursor = arcpy.UpdateCursor(fc, where_clause, "", "", sort_fields)
prevFieldValue = ""
for row in cursor:
if row.getValue("HASH") == prevFieldValue:
row.setValue("MARRIED", "YES")
cursor.updateRow(row)

prevFieldValue = row.getValue("HASH")
``````

The idea is to sort the records based on the hash, then mark the record as MARRIED if the record before it had the same HASH. Note that this only marks the 2nd person as married, though. To mark the first person as married, you would run the code again, but change the sort order of the first name...

``````sort_fields = "HASH A, FIRST_NAME D"
``````

It's important that you don't set a value if the previous HASH does not equal the current HASH so that when you run the code the 2nd time it doesn't overwrite any values you had calculated the first time.

DISCLAIMER: When I tried to run this code on some sample data it didn't seem to sort properly, so make sure to test the code before running it on 7 million records...

• Unfortunately the database is already of everyone over 18 (voter registration dbf). I was thinking that if I could subtract the two highest ages (less than 15 years difference) I could make an assumption that they are married. What about calculating a new order based on the shared address and the order of age? I would still need to try and figure out how to subtract the two highest years (oldest people). – user23148 Oct 22 '13 at 16:24

Well, it's far out of date now, but here's my two cents: I would use a dictionary to achieve this, though admittedly I don't have experience using dictionaries with such a high volume of records.

``````dictionary = {}
for row in cursor....
address_key = street number + street name + zip
last_name = last name field value
age = age field value
continue

couples = 0
for k,v in dictionary.iteritems():
ages = v[1]
if len(ages) <= 1:
continue
ages.sort().reverse
if abs(ages[0] - ages[1]) <= 15:
couples+=1
``````

Code is untested of course, but that's the overall concept: while iterating through the rows, create a dictionary whose keys are the unique address strings and whose values are a tuple. The tuple[0] is the last name and tuple [1] is a list of ages. If the cursor encounters a last name that is already listed at a given address, the age is appended to the list of ages. At the end, just run through the age lists and compare the top two numbers; if they are 15 or less apart, + 1 for the couples counter.

This doesn't take into account multiple couples with the same address, and also doesn't allow for the instances of the same street address in a given zip code... could use a little work...