I've been asked to produce a geopackage file in a specified format where one attribute is specified to be int64 nullable, and my case includes NULL values. Trying in GeoPandas, my problem is that I don't manage to create a geodataframe with a dtype=int64 containing NULL values.
I've tried adding a list of integer and None values, which becomes floats in the dataframe:
>>> import geopandas as gp
>>> from shapely.geometry import Point
>>> outdf = gp.GeoDataFrame(geometry=[Point(1, 2), Point(2, 1)])
>>> outdf['nulled_int'] = [0, None]
>>> outdf['nulled_int']
0 0.0
1 NaN
Name: nulled_int, dtype: float64
Trying to cast it to integer gives an error:
>>> outdf['nulled_int'] = outdf['nulled_int'].astype(int)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/a002001/develop/lib64/python3.6/site-packages/pandas/core/generic.py", line 5698, in astype
new_data = self._data.astype(dtype=dtype, copy=copy, errors=errors)
File "/home/a002001/develop/lib64/python3.6/site-packages/pandas/core/internals/managers.py", line 582, in astype
return self.apply("astype", dtype=dtype, copy=copy, errors=errors)
File "/home/a002001/develop/lib64/python3.6/site-packages/pandas/core/internals/managers.py", line 442, in apply
applied = getattr(b, f)(**kwargs)
File "/home/a002001/develop/lib64/python3.6/site-packages/pandas/core/internals/blocks.py", line 625, in astype
values = astype_nansafe(vals1d, dtype, copy=True)
File "/home/a002001/develop/lib64/python3.6/site-packages/pandas/core/dtypes/cast.py", line 868, in astype_nansafe
raise ValueError("Cannot convert non-finite values (NA or inf) to integer")
ValueError: Cannot convert non-finite values (NA or inf) to integer
Starting off from a Pandas series of integer type also get casted to float automatically:
>>> import pandas as pd
>>> outdf['nulled_int'] = pd.Series(dtype=int)
>>> outdf['nulled_int']
0 NaN
1 NaN
Name: nulled_int, dtype: float64
The geopackage format seems happy with nullable integer fields, I've made myself a small testfile with two integer attribute fields: nulled_int
containing a null value and integers
containing only 0 and 1:
$ ogrinfo riket_test.gpkg -al -geom=no -noextent -nomd
INFO: Open of `riket_test.gpkg'
using driver `GPKG' successful.
[...]
nulled_int: Integer64 (0.0)
integers: Integer64 (0.0)
OGRFeature(riket_test):1
nulled_int (Integer64) = 1
integers (Integer64) = 1
OGRFeature(riket_test):2
nulled_int (Integer64) = (null)
integers (Integer64) = 0
Reading this file into GeoPandas ends up in the same result as in the attempts to create it above: the field containing the NULL value gets casted to float:
>>> df = gp.read_file('riket_test.gpkg')
>>> df['nulled_int']
0 1.0
1 NaN
Name: nulled_int, dtype: float64
>>> df['integers']
0 1
1 0
Name: integers, dtype: int64
>>>
None
?None
value (which I beleave is the python equivalent to null) ends up as NaN in the dataframe.