I have the following code that was provided by bixb0012 , thank you for the merge code. I need to be able to keep a certain fields attributes/ or transfer them once the merge is done. With the following code some merged features have info in the Field2 but some doesn't. I would like to merge the features that have the same attribute from Field1 but keep/add what is in Field 2 to the new merged Field2.
Original features Merged Features
ObjectID Field1 Field 2 --> ObjectID Field1 Field2
01 CP0001 Conditional --> 1 CP0001 Conditional
02 CP0001 'Blank'
03 CP0001 'Blank'
04 CP0001 'Blank'
01 CP0014 Relocation --> 2 CP0014 Relocation
02 CP0014 'Blank'
03 CP0014 'Blank'
04 CP0014 'Blank'
from arcpy import da
from itertools import groupby
from operator import itemgetter
from functools import reduce
fc = # path to feature class or table
case_fields = ["field1", "field2"] # field(s) to group records for merging
sort_field, sort_order = "OBJECTID", "ASC"
shape_field = "SHAPE@"
fields = case_fields + [sort_field, shape_field]
sql_orderby = "ORDER BY {}, {} {}".format(", ".join(case_fields), sort_field, sort_order)
kwargs = {"in_table":fc, "field_names":fields, "sql_clause":(None, sql_orderby)}
with da.UpdateCursor(**kwargs) as ucur, da.SearchCursor(**kwargs) as scur:
case_func = itemgetter(*range(len(case_fields)))
ugroupby, sgroupby = groupby(ucur, case_func), groupby(scur, case_func)
for (ukey,ugroup),(skey,sgroup) in zip(ugroupby,sgroupby):
poly = reduce(arcpy.Geometry.union, (row[-1] for row in sgroup))
row = next(ugroup)
ucur.updateRow(row[:-1] + [poly])
for row in ugroup:
ucur.deleteRow()
When you show Field2 as 'Blank', is it literally the string 'Blank' or is it an empty string or Null?
Can Field2 have multiple non-empty/blank/null values for a given value of Field1? For example,
ObjectID Field1 Field 2 --> ObjectID Field1 Field2
01 CP0001 Conditional --> 1 CP0001 Conditional
02 CP0001 'Blank'
03 CP0001 'Blank'
04 CP0001 'Blank'
If CP0001 has a value of 'Conditional' can there only be 'Blank' or other 'Conditional' values in Field2 for CP001?
Sorry, they are Null.
Correct - If CP0001 has a value of 'Conditional' can there only be 'Blank' or other 'Conditional' values in Field2 for CP001?
Correct - Can Field2 have multiple non-empty/blank/null values for a given value of Field1?
There are some that are not duplicates, like below.
ObjectID Field1 Field 2 --> ObjectID Field1 Field2
01 CP0001 Conditional --> 1 CP0001 Conditional
02 CP0001 Conditional
03 CP0001 Null
04 CP0001 Null
05 CP0003 New ---> 5 CP00003 New
06 CP0009 Old --> 7 CP20009 Old
07 CP0011 AD Decision --> 8 CP0011 AD Decision
08 CP0011 Null
09 CP0011 Null
I made some changes to the inner most loop, try this:
for (ukey,ugroup),(skey,sgroup) in zip(ugroupby,sgroupby):
flds = list(zip(*sgroup))
poly = reduce(arcpy.Geometry.union, flds[-1])
fld2 = ",".join(set(flds[1]) - set([None]))
row = next(ugroup)
row[1] = fld2
row[-1] = poly
ucur.updateRow(row)
for row in ugroup:
ucur.deleteRow()
Thank you for the response, with the change you provided it looks like it skipped the ones with the same P_ID that had at least one blank/null in Field1 but joined the ones with the same P_ID that had Field1 populated for all those records. Also I just noticed that some Duplicate P_ID don't have anything in Field1 and if that is the case I would like Field1 populated with Field2, for example WI2018-0137. I have attached the data to reference. I really appreciate you help.
It's good you included some sample data because your example doesn't quite explain it completely.
Are you working natively with shape files or feature classes? I ask because your text fields don't contain any NULLs in the sample data you uploaded, which is expected for shape files, but you mentioned above they have some NULLs.
When a P_ID has no records that contain a non-NULL/non-empty Field1, how do you want it handled? Is it possible for Field1 or Field2 to have more than one value for a given P_ID? if so, how do you want to handle that situation?
It would be in a geodatabase, I exported it out of the geodatabase for testing sorry about the confusion . If a P_ID has no record in field1 I would like it to populate field1 with what is in field two if there is something in field2. There will be some that don't have anything in field1 and field2 and if that is the case just pass on that records. Field1 and Field2 shouldn't have more than one value.