Skip to content

Commit

Permalink
[Ready for Review] Pandas 2.0 compatibility (#569)
Browse files Browse the repository at this point in the history
fixes #512

Authors:
  - Ajay Thorve (https://github.com/AjayThorve)

Approvers:
  - GALI PREM SAGAR (https://github.com/galipremsagar)
  - Jake Awe (https://github.com/AyodeAwe)
  - Allan (https://github.com/exactlyallan)

URL: #569
  • Loading branch information
AjayThorve authored Feb 9, 2024
1 parent 8c4c3fc commit bb275b2
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 27 deletions.
2 changes: 1 addition & 1 deletion conda/environments/all_cuda-118_arch-x86_64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ dependencies:
- jupyter_sphinx
- libwebp
- nbsphinx
- nodejs>=14
- nodejs>=18
- notebook>=0.5.0
- numba>=0.57
- numpy>=1.21
Expand Down
2 changes: 1 addition & 1 deletion conda/environments/all_cuda-120_arch-x86_64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ dependencies:
- jupyter_sphinx
- libwebp
- nbsphinx
- nodejs>=14
- nodejs>=18
- notebook>=0.5.0
- numba>=0.57
- numpy>=1.21
Expand Down
2 changes: 1 addition & 1 deletion dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ dependencies:
- output_types: conda
packages:
- cupy>=12.0.0
- nodejs>=14
- nodejs>=18
- libwebp
- output_types: [requirements, pyproject]
packages:
Expand Down
3 changes: 2 additions & 1 deletion python/cuxfilter/assets/geojson_mapper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from urllib.request import urlopen
import geopandas as gpd
import pandas as pd
from io import StringIO


def geo_json_mapper(
Expand All @@ -16,7 +17,7 @@ def geo_json_mapper(

temp_gpd_df = gpd.read_file(data).to_crs(epsg=projection)

df = pd.read_json(temp_gpd_df.to_json())
df = pd.read_json(StringIO(temp_gpd_df.to_json()))

x_range = (
temp_gpd_df.geometry.bounds.minx.min(),
Expand Down
2 changes: 1 addition & 1 deletion python/cuxfilter/charts/bokeh/plots/bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def calculate_source(self, data=None):
Output:
cudf.DataFrame
"""
data = data or self.source
data = self.source if data is None else data
return calc_groupby(self, data)

def reload_chart(self, data):
Expand Down
2 changes: 1 addition & 1 deletion python/cuxfilter/charts/bokeh/plots/histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def calculate_source(self, data=None):
Output:
cudf.DataFrame
"""
data = data or self.source
data = self.source if data is None else data
return calc_value_counts(
data[self.x],
self.stride,
Expand Down
4 changes: 2 additions & 2 deletions python/cuxfilter/charts/core/aggregate/core_aggregate.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,12 @@ def reset_callback(resetting):
def get_box_select_callback(self, dashboard_cls):
def cb(bounds, x_selection, y_selection):
self.box_selected_range, self.selected_indices = None, None
if type(x_selection) == tuple:
if isinstance(x_selection, tuple):
self.box_selected_range = {
self.x + "_min": x_selection[0],
self.x + "_max": x_selection[1],
}
elif type(x_selection) == list:
elif isinstance(x_selection, list):
self.selected_indices = (
dashboard_cls._cuxfilter_df.data[self.x]
.isin(x_selection)
Expand Down
2 changes: 1 addition & 1 deletion python/cuxfilter/charts/core/non_aggregate/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ def point_in_polygon(df, x, y, polygons):
polygons = cuspatial.GeoSeries(
gpd.GeoSeries(Polygon(polygons)), index=["selection"]
)
return cuspatial.point_in_polygon(points, polygons)
return cuspatial.point_in_polygon(points, polygons).selection
5 changes: 3 additions & 2 deletions python/cuxfilter/charts/deckgl/bindings/panel_deck.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class PanelDeck(param.Parameterized):

@property
def valid_indices(self):
return self.indices.intersection(self.data.index)
return list(self.indices.intersection(self.data.index))

def get_tooltip_html(self):
"""
Expand Down Expand Up @@ -110,7 +110,8 @@ def click_event(self):
temp_colors = self.colors.copy()
if len(self.indices) > 0:
temp_colors.loc[
set(self.data.index) - self.indices, self.colors.columns
list(set(self.data.index) - self.indices),
self.colors.columns,
] = self.default_color
self.data[self.colors.columns] = temp_colors
self._update_layer_data(self.data)
Expand Down
31 changes: 18 additions & 13 deletions python/cuxfilter/charts/panel_widgets/plots.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
from ..core import BaseWidget
from ..core.aggregate import BaseNumberChart
from ..constants import (
Expand Down Expand Up @@ -160,7 +161,10 @@ def compute_query_dict(self, query_str_dict, query_local_variables_dict):
reference to dashboard.__cls__.query_dict
"""
if self.chart.value != (self.chart.start, self.chart.end):
min_temp, max_temp = self.chart.value
min_temp, max_temp = (
datetime.datetime.fromordinal(x.toordinal())
for x in self.chart.value
)
query = f"@{self.x}_min<={self.x}<=@{self.x}_max"
query_str_dict[self.name] = query
query_local_variables_dict[self.x + "_min"] = min_temp
Expand Down Expand Up @@ -328,9 +332,7 @@ def initiate_chart(self, dashboard_cls):
self.min_value, self.max_value = get_min_max(
dashboard_cls._cuxfilter_df.data, self.x
)
self.source = dashboard_cls._cuxfilter_df.data[self.x].reset_index(
drop=True
)
self.source = dashboard_cls._cuxfilter_df.data[self.x]
self.calc_list_of_values(dashboard_cls._cuxfilter_df.data)
self.generate_widget()
self.add_events(dashboard_cls)
Expand Down Expand Up @@ -396,17 +398,20 @@ def compute_query_dict(self, query_str_dict, query_local_variables_dict):
if len(self.chart.value) == 0:
query_str_dict.pop(self.name, None)
else:
df_module = (
cudf if isinstance(self.source, cudf.Series) else dask_cudf
)

if self.source.dtype == "object":
query_str_dict[self.name] = df_module.DataFrame(
self.source.str.contains("|".join(self.chart.value))
def filter_source(s: cudf.Series, v: list):
if s.dtype == "object":
return s.str.contains("|".join(v))
else:
return s.isin(v)

if isinstance(self.source, dask_cudf.Series):
query_str_dict[self.name] = self.source.map_partitions(
filter_source, self.chart.value
)
else:
query_str_dict[self.name] = df_module.DataFrame(
self.source.isin(self.chart.value)
elif isinstance(self.source, cudf.Series):
query_str_dict[self.name] = filter_source(
self.source, self.chart.value
)

def apply_theme(self, theme):
Expand Down
13 changes: 10 additions & 3 deletions python/cuxfilter/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def queried_indices(self):
"""
Read-only propery queried_indices returns a merged index
of all queried index columns present in self._query_str_dict
as a cudf.Series.
as a `cudf.Series` or `dask_cudf.Series`.
Returns None if no index columns are present.
Expand All @@ -132,13 +132,20 @@ def queried_indices(self):
else dask_cudf
)
selected_indices = {
key: value
key: value.reset_index(drop=True)
for (key, value) in self._query_str_dict.items()
if type(value) in [cudf.DataFrame, dask_cudf.DataFrame]
if type(value)
in [
cudf.DataFrame,
dask_cudf.DataFrame,
cudf.Series,
dask_cudf.Series,
]
}
if len(selected_indices) > 0:
result = (
df_module.concat(list(selected_indices.values()), axis=1)
.set_index(self._cuxfilter_df.data.index)
.fillna(False)
.all(axis=1)
)
Expand Down
1 change: 1 addition & 0 deletions python/cuxfilter/tests/charts/deckgl/test_deckgl.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def test_init(self, cux_df):
)

assert choropleth3d_chart.chart.indices == set()
assert choropleth3d_chart.chart.valid_indices == list()

assert choropleth3d_chart.chart.multi_select is False

Expand Down

0 comments on commit bb275b2

Please sign in to comment.