|
POST
|
This is an interesting problem but I think I found a solution using defaultdict. # import arcpy
from collections import defaultdict
# Example pipe data
pipe_data = [(12, 'red', 1.5), (12, 'blue', 2.2), (12, 'red', 3.3), (24, 'blue', 4.99), (24, 'red', 1.05), (24, 'blue', 4.2)]
# Real pipe data
# pipe_fields = ["diameter", "material", "SHAPE@LENGTH"]
# pipe_data = [row for row in arcpy.da.SearchCursor(pipe_fc, pipe_fields)]
pipe_diameters = {row[0]: None for row in pipe_data}
for diameter in pipe_diameters:
# Collect all rows with the given diameter
diameter_materials = [(row[1], row[2]) for row in pipe_data if row[0] == diameter]
# Define and build dictionary with total lengths for each material in the given diameter
material_lengths = defaultdict(float)
for material, length in diameter_materials:
material_lengths[material] += length
# Put the resulting material/lengths as a value for the diameter
pipe_diameters[diameter] = dict(material_lengths)
# Total length of all materials for this diameter
pipe_diameters[diameter]["diameter_length"] = sum(material_lengths.values())
# Report data for demonstration purposes.
# dict.pop() is destructive, removing the diameter_length entry from each diameter.
# Do not do this if you need to use diameter_length again later!
for diameter, values in pipe_diameters.items():
print(f"{diameter} diameter total length: {values.pop('diameter_length')}")
for material, length in values.items():
print(f"\t{material} length: {length}") Also, reading your code sample was really hard to follow because of your variable names. Try using more descriptive names to make the code more "self documenting". Your successors will thank you! Also, this might be a copy/paste issue, but standard Python formatting calls for exactly four spaces as indentation.
... View more
07-09-2021
11:42 AM
|
1
|
2
|
3101
|
|
POST
|
Does it matter how ties are broken (if two or more fields have the same maximum value)?
... View more
07-09-2021
07:14 AM
|
1
|
2
|
1817
|
|
POST
|
I may be mixing up projects and grids but I think you get the idea. Just do the spatial join, put it into a dictionary with project as key and the value is a list of intersecting grids. Then you can do what you need with it, like write it back to your feature class as a comma separated list of values. from collections import defaultdict
try:
# Perform spatial join between grid and project features.
grid_project_spatialjoin_inmem = r"in_memory\grid_project_spatialjoin"
arcpy.SpatialJoin_analysis(
target_features=projectFeatures,
join_features=gridFeatures,
out_feature_class=grid_project_spatialjoin_inmem,
join_operation="JOIN_ONE_TO_MANY"
)
# Create dictionary keys of projects and values with list of grids
project_grids = defaultdict(list)
with arcpy.da.SearchCursor(grid_project_spatialjoin_inmem, ("projectPageName", "gridLabel")) as sCursor:
for projectPageName, gridLabel in sCursor:
project_grids[projectPageName].append(gridLabel)
finally:
arcpy.Delete_management("in_memory")
# Write the intersecting grids for each project as comma separated list
with arcpy.da.UpdateCursor(gridFeatures, ("projectPageName", "gridLabel")) as uCursor:
for projectPageName, gridLabel in uCursor:
grid_list = project_grids.get(projectPageName, "")
uCursor.updateRow((projectPageName, ", ".join(grid_list))) EDIT: fixed a comment for creating the dictionary
... View more
07-08-2021
02:47 PM
|
1
|
2
|
1579
|
|
POST
|
So would a rule be that if the number is over 4 digits, the remainder is taken from the beginning of the number and used as the zone? So if the number was 2361867, the zone would be 236?
... View more
07-08-2021
07:25 AM
|
0
|
1
|
5563
|
|
POST
|
@JamesWilcox1970, this is a new requirement from your initial post. Please describe all the rules in which these projects are grouped into index grids and we can help you find a solution.
... View more
07-07-2021
08:27 PM
|
0
|
4
|
3046
|
|
POST
|
I like dict.get() because it returns None by default if the key is not found. You can specify a different value in the second argument but None is redundant.
... View more
07-07-2021
03:56 PM
|
0
|
1
|
3052
|
|
POST
|
Here's a blog you should read. It's got some techniques for doing stuff like this that I have found very useful. Turbo Charging Data Manipulation with Python Curso... - Esri Community Basically you'll read your "look up" data into a dictionary and reference it by some id to get the value you want to write elsewhere. If I'm understanding your logic correctly, it would look something like this. # UpdateCursor to add all index grid cells for each label
gridList = {label: pageName for label, pageName in arcpy.da.SearchCursor(intersectOut, ("Label", "PageName"))} # List from intersection
arcpy.AddMessage("Grid list = {}".format(gridList)) # For debugging
with arcpy.da.UpdateCursor(indexTable, ("Label", "PageName")) as uCursor:
for label, pageName in uCursor:
gridList_pageName = gridList.get(label)
arcpy.AddMessage(gridList_pageName)
# Before going to the next record in the site index table
# write the PageName from gridList if there is one.
if gridList_pageName:
uCursor.updateRow((label, gridList_pageName))
else:
arcpy.AddWarning("Label {} not found in gridList; nothing updated.".format(label))
... View more
07-07-2021
08:46 AM
|
1
|
9
|
3060
|
|
POST
|
Try changing line 11 to include the field name you are trying to get (PARCELNUM) parcelnum = feat.PARCELNUM; Also, it looks like you're only getting the PARCELNUM of the first record from the first query and the second query is only highlighting the first record. Is that correct?
... View more
07-06-2021
01:55 PM
|
0
|
0
|
4760
|
|
POST
|
If you use the "NO_TEST" option for schema_type, you also need to use the field_mapping parameter to specify which fields can get mapped together. I've never tried NO_TEST without field_mappings but maybe this is the result. Append in memory workspace should work.
... View more
07-06-2021
07:54 AM
|
0
|
0
|
2024
|
|
POST
|
How you are dividing up 34 zones? I mentioned in my post that if you are using the first digit, you'll only get nine zones before it starts repeating (1 through 9).
... View more
07-06-2021
07:39 AM
|
0
|
3
|
5598
|
|
POST
|
What about this spiffy trick where you can reference the values of a row by field name using a dictionary? def rows_as_dicts(cursor):
colnames = cursor.fields
for row in cursor:
yield dict(zip(colnames, row))
with arcpy.da.SearchCursor(r'c:\data\world.gdb\world_cities', '*') as sc:
for row in rows_as_dicts(sc):
print row['CITY_NAME'] Getting arcpy.da rows back as dictionaries | ArcPy Café (wordpress.com)
... View more
07-02-2021
01:41 PM
|
0
|
1
|
2437
|
|
POST
|
Is your goal to have one feature class with everything smashed into it (as many spatial joins) or to have separate feature classes, each spatial joined to only Parcels?
... View more
07-02-2021
09:21 AM
|
0
|
1
|
1753
|
|
POST
|
Did you restart Web AppBuilder after you copied the files into ..\client\stemapp\widgets
... View more
07-01-2021
09:40 AM
|
0
|
1
|
4364
|
|
POST
|
Spatial join is an inherently intensive operation and there's not much you can do to improve that. Indexes, multithreading, maybe using memory workspace. The looping is how I would go about doing it. You could consider using field mappings when you copy the data to memory and keep only the necessary fields but that's a lot more work because you have to have a list of keep fields for every feature class. Also, looking at your code, it looks like you'll end up spatial joining fc1 to its self when it gets to that in the fcs list.
... View more
06-30-2021
04:43 PM
|
1
|
3
|
5402
|
|
POST
|
Is there some new requirement that you only need to null out fields that are not null? It's okay if CalculateField nulls an already null field value; you don't need to query them out. If you want to do a query first, either use Select Layer By Attribute first or (what I would recommend) is using the UpdateCursor method mentioned by @curtvprice.
... View more
06-28-2021
09:17 AM
|
0
|
0
|
6712
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 3 weeks ago | |
| 1 | 10-23-2025 03:53 PM | |
| 1 | 04-28-2026 07:25 AM | |
| 1 | 03-19-2026 08:59 AM | |
| 1 | 02-12-2026 01:37 PM |