Select to view content in your preferred language

IsInstance() not registering column type as integer in arcgis.features.FeatureSet.from_dataframe()

932
1
08-24-2023 03:59 PM
Macy12345
Emerging Contributor

This script was previously working with version 2.9 of ArcGIS Pro, with the caveat that I had to change my sdf creation function to flayer.query().sdf.

 

I have this line in my script:

 

add_ss = arcgis.features.FeatureSet.from_dataframe(new_ss_df)

 

 

When I run the script after upgrading to v3.1.4, I get this error:

 

Traceback (most recent call last):
  File "C:\folder\file.py", line 268, in 
    add_ss = arcgis.features.FeatureSet.from_dataframe(new_ss_df)
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\features\feature.py", line 899, in from_dataframe
    fs = FeatureSet.from_dict(df.spatial.__feature_set__)
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\features\geo\_accessor.py", line 2990, in __feature_set__
    l = df[col].str.len().max()
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\pandas\core\generic.py", line 5487, in __getattr__
    return object.__getattribute__(self, name)
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\pandas\core\accessor.py", line 181, in __get__
    accessor_obj = self._accessor(obj)
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\pandas\core\strings\accessor.py", line 168, in __init__
    self._inferred_dtype = self._validate(data)
  File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\pandas\core\strings\accessor.py", line 225, in _validate
    raise AttributeError("Can only use .str accessor with string values!")
AttributeError: Can only use .str accessor with string values!

(Posted the wrong error message at first and corrected it.)

 

 

I went to the accessor.py file and copied the code I was getting hung up on, which looks like this:

 

cols_norm = [col for col in df.columns]
...
for col in cols_norm:
            try:
                idx = df[col].first_valid_index()
                col_val = df[col].loc[idx]
            except:
                col_val = ""
            if isinstance(col_val, (str, np.str)) and not col in date_cols:
                l = df[col].str.len().max()

 

 

Then I used .dtypes to make sure that my columns were the expected type (they were) and ran the stand-alone code on my data. Isinstance() consistently registered my int32 and int64 columns as a str column and then ran it through the last line of the code above, which threw the error and broke the code. I then tried checking the type in a different way and the code works:

 

cols_norm = [col for col in new_ss_df.columns]
for col in cols_norm:
    try:
        idx = df[col].first_valid_index()
        col_val = df[col].loc[idx]
    except:
        col_val = ""
    if new_ss_df.dtypes[col] == object:
        print(col)
        print(new_ss_df[col].str.len().max())

 

 

But while that narrows down the problem, it unfortunately doesn't help me because the arcgis.features.FeatureSet.from_dataframe() function still uses isinstance().

Has anybody run into this problem and found a workaround?

 

Thank you for your time,

Macy

 

0 Kudos
1 Reply
Macy12345
Emerging Contributor

The isinstance() in the from_dataframe() function wouldn't recognize my integer column type because I had a null (or possibly all nulls) in the column, despite the column being typed correctly when using dtypes.

In addition it seems you also can't update a row within a feature class if that row has a null in an integer field, so I had to go into the feature class and fill those in before using edit_features.

I believe at least the second one is new behavior that started in either July or August of this year, as my script had previously been working fine for almost two years. I wouldn't be surprised if the first was new as well, but it's possible I've never before had an integer column that was all nulls in my update dataframe.

 

Thanks,

Macy

0 Kudos