-
Hi folks, Ibis newb here.
This raise the following error in a Jupyter notebook.
How to get this right? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 6 replies
-
Hey @araichev ! So, huge caveat here that I, uh, don't really know anything about but here goes! First, we import a few things and read in the CSV: [ins] In [1]: import ibis
[ins] In [2]: from ibis import _
[ins] In [3]: con = ibis.duckdb.connect(extensions=["spatial"]) # explicit DuckDB connection with geospatial extension loaded
[ins] In [4]: t = con.read_csv("/home/gil/Downloads/shapes.csv")
[ins] In [5]: ibis.options.interactive = True
[ins] In [6]: t
Out[6]:
┏━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ shape_id ┃ shape_pt_lat ┃ shape_pt_lon ┃ shape_pt_sequence ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ string │ float64 │ float64 │ int64 │
├──────────┼──────────────┼──────────────┼───────────────────┤
│ 1100015 │ -16.743632 │ 145.668255 │ 10001 │
│ 1100015 │ -16.743522 │ 145.668394 │ 10002 │
│ 1100015 │ -16.741258 │ 145.671277 │ 10003 │
│ 1100015 │ -16.744007 │ 145.671074 │ 10004 │
│ 1100015 │ -16.744015 │ 145.671074 │ 10005 │
│ 1100015 │ -16.744015 │ 145.671074 │ 20001 │
│ 1100015 │ -16.744732 │ 145.671060 │ 20002 │
│ 1100015 │ -16.747083 │ 145.670999 │ 20003 │
│ 1100015 │ -16.749574 │ 145.671118 │ 20004 │
│ 1100015 │ -16.749645 │ 145.669650 │ 20005 │
│ … │ … │ … │ … │
└──────────┴──────────────┴──────────────┴───────────────────┘ Next, we want to convert those lat/long to points instead (now here's where I might be doing this in the wrong order, but you can reverse as needed): [ins] In [9]: t = t.select(t.shape_id, t.shape_pt_sequence, point=t.shape_pt_lat.point(t.shape_pt_lon)
...: )
[ins] In [10]: t
Out[10]:
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ shape_id ┃ shape_pt_sequence ┃ point ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string │ int64 │ point:geometry │
├──────────┼───────────────────┼───────────────────────────┤
│ 1100015 │ 10001 │ <POINT (-16.744 145.668)> │
│ 1100015 │ 10002 │ <POINT (-16.744 145.668)> │
│ 1100015 │ 10003 │ <POINT (-16.741 145.671)> │
│ 1100015 │ 10004 │ <POINT (-16.744 145.671)> │
│ 1100015 │ 10005 │ <POINT (-16.744 145.671)> │
│ 1100015 │ 20001 │ <POINT (-16.744 145.671)> │
│ 1100015 │ 20002 │ <POINT (-16.745 145.671)> │
│ 1100015 │ 20003 │ <POINT (-16.747 145.671)> │
│ 1100015 │ 20004 │ <POINT (-16.75 145.671)> │
│ 1100015 │ 20005 │ <POINT (-16.75 145.67)> │
│ … │ … │ … │
└──────────┴───────────────────┴───────────────────────────┘ Now we want to order the columns and group by We need to specify the output type of the function, and make sure that the name of our "blank" function matches the DuckDB function we want to use: [ins] In [11]: import ibis.expr.datatypes as dt
[nav] In [12]: @ibis.udf.scalar.builtin
...: def ST_MakeLine(*col0) -> dt.LineString:
...: ... Now we can do that order_by, group_by, and agg, and pass the collected points to [nav] In [13]: t.order_by(t.shape_id, t.shape_pt_sequence).group_by(t.shape_id).aggregate(geometry=ST_MakeLi
...: ne(_.point.collect()))
Out[13]:
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ shape_id ┃ geometry ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ string │ linestring:geometry │
├──────────┼──────────────────────────────────────────────────────────────────────────────────┤
│ 1400001 │ <LINESTRING (-17.034 145.74, -17.033 145.74, -17.033 145.74, -17.033 145.74,...> │
│ 1420013 │ <LINESTRING (-17.026 145.728, -17.026 145.73, -17.025 145.731, -17.025 145.7...> │
│ 143W0012 │ <LINESTRING (-16.921 145.779, -16.921 145.779, -16.92 145.778, -16.92 145.77...> │
│ 150E0007 │ <LINESTRING (-17.087 145.767, -17.088 145.767, -17.088 145.766, -17.089 145....> │
│ 150E0009 │ <LINESTRING (-16.921 145.779, -16.921 145.779, -16.92 145.778, -16.92 145.77...> │
│ 1100015 │ <LINESTRING (-16.744 145.668, -16.744 145.668, -16.741 145.671, -16.744 145....> │
│ 1100023 │ <LINESTRING (-16.746 145.665, -16.744 145.667, -16.744 145.668, -16.744 145....> │
│ 110N0010 │ <LINESTRING (-16.746 145.665, -16.744 145.667, -16.744 145.668, -16.744 145....> │
│ 1110015 │ <LINESTRING (-16.791 145.681, -16.79 145.68, -16.789 145.68, -16.789 145.679...> │
│ 1110016 │ <LINESTRING (-16.92 145.779, -16.92 145.778, -16.92 145.778, -16.92 145.778,...> │
│ … │ … │
└──────────┴──────────────────────────────────────────────────────────────────────────────────┘ I hope that helps! |
Beta Was this translation helpful? Give feedback.
-
Thanks heaps, @gforsyth ! Follow up question for you: If
|
Beta Was this translation helpful? Give feedback.
-
P.P.S. Bonus question: how to write the inverse function?
|
Beta Was this translation helpful? Give feedback.
Thanks heaps, @gforsyth !
That works, and i've put the complete function together below for future readers of this thread.
Follow up question for you: If
MakeLine
were exposed in Ibis, how should i change my function?