I have a script that runs fine as a toolbox script in Desktop Pro, however when I try to run the same script in ArcGIS Online as a notebook, I get the following error:
TypeError: float() argument must be a string or a number, not 'dict'
For this line of code:
new_feature_layer = sdf.spatial.to_featurelayer(
title=f"Polys Centroids {tmp_uuid}",
gis=gis,
tags=["centroids", "outputs"],
folder=TMP_FOLDER,
sanitize_columns=False,
service_name=f"polys_centroids_{tmp_uuid}",
)
Here's the full stack trace for the error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_59/1392681058.py in <cell line: 2396>()
2422 param7
2423 )
-> 2424 main(_args)
/tmp/ipykernel_59/1392681058.py in main(_args)
64 print("PROCESSING FOR POLYS")
65 _args.set_is_polys(True)
---> 66 run_steps(_args)
67
68
/tmp/ipykernel_59/1392681058.py in run_steps(_args)
70 if not _args.is_test_mode:
71 print("Starting download step")
---> 72 download(_args)
73 print("Completed download step")
74 print("Starting join step...")
/tmp/ipykernel_59/1392681058.py in download(_args)
133 layer_item = gis.content.get(layer_id)
134 if _args.is_polys:
--> 135 polys_feature_layer = generate_points(_args)
136 output_file_centroids = polys_feature_layer.export(
137 title="Polys_with_centroids",
/tmp/ipykernel_59/1392681058.py in generate_points(_args)
113 )
114 print(tmp_uuid)
--> 115 new_feature_layer = sdf.spatial.to_featurelayer(
116 title=f"Polys Centroids {tmp_uuid}",
117 gis=gis,
/opt/conda/lib/python3.9/site-packages/arcgis/features/geo/_accessor.py in to_featurelayer(self, title, gis, tags, folder, sanitize_columns, service_name, **kwargs)
2844 )
2845
-> 2846 result = content.import_data(
2847 self._data,
2848 folder=folder,
/opt/conda/lib/python3.9/site-packages/arcgis/gis/__init__.py in import_data(self, df, address_fields, folder, item_id, **kwargs)
7562 )
7563
-> 7564 ds = df.spatial.to_featureclass(
7565 location=os.path.join(temp_dir, name),
7566 sanitize_columns=sanitize_columns,
/opt/conda/lib/python3.9/site-packages/arcgis/features/geo/_accessor.py in to_featureclass(self, location, overwrite, has_z, has_m, sanitize_columns)
2635 origin_columns = self._data.columns.tolist()
2636 origin_index = copy.deepcopy(self._data.index)
-> 2637 result = to_featureclass(
2638 self,
2639 location=location,
/opt/conda/lib/python3.9/site-packages/arcgis/features/geo/_io/fileops.py in to_featureclass(geo, location, overwrite, validate, sanitize_columns, has_m, has_z)
1106 return res
1107 else:
-> 1108 res = _pyshp2(df=df, out_path=out_location, out_name=fc_name)
1109 df.set_index(old_idx)
1110 return res
/opt/conda/lib/python3.9/site-packages/arcgis/features/geo/_io/fileops.py in _pyshp2(df, out_path, out_name)
1334 if value is np.nan:
1335 row[idx] = None
-> 1336 shpfile.record(*row)
1337 del idx
1338 del row
/opt/conda/lib/python3.9/site-packages/shapefile.py in record(self, *recordList, **recordDict)
1835 # Blank fields for empty record
1836 record = ["" for field in self.fields if field[0] != 'DeletionFlag']
-> 1837 self.__dbfRecord(record)
1838
1839 def __dbfRecord(self, record):
/opt/conda/lib/python3.9/site-packages/shapefile.py in __dbfRecord(self, record)
1870 value = format(value, "d")[:size].rjust(size) # caps the size if exceeds the field size
1871 else:
-> 1872 value = float(value)
1873 value = format(value, ".%sf"%deci)[:size].rjust(size) # caps the size if exceeds the field size
1874 elif fieldType == "D":
TypeError: float() argument must be a string or a number, not 'dict'
And this is the surrounding code in the method where the error occurs:
def generate_points(_args):
gis = _args.gis
poly_feature_layer = gis.content.get("7da90f1a777c4d6e9d59e3314e70fbe5")
print(poly_feature_layer["url"])
poly_feature_layer2 = FeatureLayer(poly_feature_layer["url"] + "/0")
# EPSG 4326 is a coordinate system for lat/long that makes used of the WGS84
# spheroid
sr = 4326
df = poly_feature_layer2.query(
as_df=True, return_centroid=True, return_geometry=False, out_sr=sr
)
print("Here 61")
print(df.iloc[0])
# Convert centroid to dict
sdf = GeoAccessor.from_xy(
df.join(pd.DataFrame(df.loc[:, "centroid"].to_dict()).T),
"x",
"y",
sr=sr,
)
print("Here 62")
print(sdf.iloc[0])
sdf = sdf.drop("Correct_Area_SqM", axis=1)
print("Here 63")
print(sdf.iloc[0])
# Create a shortened uuid to avoid name clashes.
# We made want to add cleanup for all temporary layers.
tmp_uuid = "".join(
random.choice(string.ascii_letters + string.digits) for _ in range(6)
)
print(tmp_uuid)
new_feature_layer = sdf.spatial.to_featurelayer(
title=f"Polys Centroids {tmp_uuid}",
gis=gis,
tags=["centroids", "outputs"],
folder=TMP_FOLDER,
sanitize_columns=False,
service_name=f"polys_centroids_{tmp_uuid}",
)
return new_feature_layer
Solved! Go to Solution.
Update - I was able to get this issue (and some others that were also related) resolved by switching from the Standard to the Advanced runtime.
Donald, you would be better off filing an issue with Tech Support, or better still, file one on the arcgis github site
Esri/arcgis-python-api: Documentation and samples for ArcGIS API for Python (github.com)
Ok, thanks for the suggestion
Update - I was able to get this issue (and some others that were also related) resolved by switching from the Standard to the Advanced runtime.