Skip to content
25 changes: 24 additions & 1 deletion marimo/_output/data/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io
from typing import Any, Union

from marimo._dependencies.dependencies import DependencyManager
from marimo._plugins.core.media import is_data_empty
from marimo._runtime.virtual_file import (
EMPTY_VIRTUAL_FILE,
Expand Down Expand Up @@ -237,5 +238,27 @@ def convert_bigint(obj: Any) -> Any:
convert_bigint(as_json),
indent=None,
separators=(",", ":"),
default=str,
default=custom_json,
)


def custom_json(obj: Any) -> Any:
if hasattr(obj, "_mime_"):
mimetype, data = obj._mime_()
return {"mimetype": mimetype, "data": data}

if DependencyManager.pandas.imported():
import pandas as pd

# TODO: Port this logic over to msgspec encoder
if isinstance(
obj,
(
pd.TimedeltaIndex,
pd.DatetimeIndex,
pd.IntervalIndex,
pd.PeriodIndex,
),
):
return obj.astype(str).tolist()
return str(obj)
21 changes: 7 additions & 14 deletions marimo/_plugins/ui/_impl/tables/pandas_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ def to_csv_str(
def to_json_str(
self, format_mapping: Optional[FormatMapping] = None
) -> str:
def to_json(result: pd.DataFrame) -> list[dict[str, Any]]:
# Use to_dict instead of to_json
# nans, infs, -infs are properly serialized
return result.to_dict(orient="records") # type: ignore

from pandas.api.types import (
is_complex_dtype,
is_object_dtype,
Expand Down Expand Up @@ -123,13 +128,7 @@ def to_json_str(
"Error handling complex or timedelta64 dtype",
exc_info=e,
)
return sanitize_json_bigint(
result.to_json(
orient="records",
date_format="iso",
default_handler=str,
)
)
return sanitize_json_bigint(to_json(result))

# Flatten row multi-index
if isinstance(result.index, pd.MultiIndex) or (
Expand Down Expand Up @@ -182,13 +181,7 @@ def to_json_str(
"Indexes with more than one level are not well supported, call reset_index() or use mo.plain(df)"
)

return sanitize_json_bigint(
result.to_json(
orient="records",
date_format="iso",
default_handler=str,
)
)
return sanitize_json_bigint(to_json(result))

def _infer_dtype(self, column: ColumnName) -> str:
# Typically, pandas dtypes returns a generic dtype
Expand Down
14 changes: 8 additions & 6 deletions marimo/_smoke_tests/tables/big_ints.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import marimo

__generated_with = "0.15.5"
__generated_with = "0.17.6"
app = marimo.App(width="medium")


@app.cell(hide_code=True)
def _(mo):
mo.md(r"""## Big Ints""")
mo.md(r"""
## Big Ints
""")
return


Expand Down Expand Up @@ -34,18 +36,18 @@ def _():


@app.cell
def _(data):
def _(data, mo):
import pandas as pd

pd.DataFrame(data)
mo.vstack([mo.plain(pd.DataFrame(data)), pd.DataFrame(data)])
return


@app.cell
def _(data):
def _(data, mo):
import polars as pl

pl.DataFrame(data)
mo.vstack([mo.plain(pl.DataFrame(data)), pl.DataFrame(data)])
return


Expand Down
2 changes: 1 addition & 1 deletion marimo/_smoke_tests/tables/images.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import marimo

__generated_with = "0.15.5"
__generated_with = "0.17.8"
app = marimo.App(width="medium")


Expand Down
42 changes: 42 additions & 0 deletions marimo/_smoke_tests/tables/nans.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import marimo

__generated_with = "0.17.6"
app = marimo.App(width="medium")


@app.cell
def _():
import marimo as mo
import polars as pl
import pandas as pd
import numpy as np
return mo, np, pd, pl


@app.cell
def _(mo, np, pl):
polars_df = pl.DataFrame({"nans": [1.0, np.nan, np.inf, -np.inf, None]})
mo.vstack([mo.plain(polars_df), polars_df])
return


@app.cell
def _(np, pd, pl):
pl.DataFrame(
{"nans_not_strict": [1.0, np.nan, np.inf, -np.inf, None, pd.NA, pd.NaT]},
strict=False,
)
return


@app.cell
def _(mo, np, pd):
pandas_df = pd.DataFrame(
{"nans": [1, None, pd.NaT, np.nan, pd.NA, np.inf, -np.inf]}
)
mo.vstack([mo.plain(pandas_df), pandas_df])
return


if __name__ == "__main__":
app.run()
143 changes: 88 additions & 55 deletions tests/_plugins/ui/_impl/tables/snapshots/narwhals.json
Original file line number Diff line number Diff line change
@@ -1,56 +1,89 @@
[
{
"strings": "a",
"bool": true,
"int": 1,
"float": 1.0,
"datetime": "2021-01-01 00:00:00",
"date": "2021-01-01",
"struct": { "a": 1, "b": 2 },
"list": [1, 2],
"array": [1],
"nulls": null,
"category": "cat",
"set": "{1, 2}",
"imaginary": "(1+2j)",
"time": "12:30:00",
"duration": "1 day, 0:00:00",
"mixed_list": ["1", "two"]
},
{
"strings": "b",
"bool": false,
"int": 2,
"float": 2.0,
"datetime": "2021-01-02 00:00:00",
"date": "2021-01-02",
"struct": { "a": 3, "b": 4 },
"list": [3, 4],
"array": [2],
"nulls": "data",
"category": "dog",
"set": "{3, 4}",
"imaginary": "(3+4j)",
"time": "13:45:00",
"duration": "2 days, 0:00:00",
"mixed_list": ["3.0", "0.0"]
},
{
"strings": "c",
"bool": true,
"int": 3,
"float": 3.0,
"datetime": "2021-01-03 00:00:00",
"date": "2021-01-03",
"struct": { "a": 5, "b": 6 },
"list": [5, 6],
"array": [3],
"nulls": null,
"category": "mouse",
"set": "{5, 6}",
"imaginary": "(5+6j)",
"time": "14:15:00",
"duration": "3 days, 0:00:00",
"mixed_list": [null, "2021-01-01 00:00:00.000000"]
}
]
{
"strings": "a",
"bool": true,
"int": 1,
"float": 1.0,
"datetime": "2021-01-01 00:00:00",
"date": "2021-01-01",
"struct": {
"a": 1,
"b": 2
},
"list": [
1,
2
],
"array": [
1
],
"nulls": null,
"category": "cat",
"set": "{1, 2}",
"imaginary": "(1+2j)",
"time": "12:30:00",
"duration": "1 day, 0:00:00",
"mixed_list": [
"1",
"two"
]
},
{
"strings": "b",
"bool": false,
"int": 2,
"float": 2.0,
"datetime": "2021-01-02 00:00:00",
"date": "2021-01-02",
"struct": {
"a": 3,
"b": 4
},
"list": [
3,
4
],
"array": [
2
],
"nulls": "data",
"category": "dog",
"set": "{3, 4}",
"imaginary": "(3+4j)",
"time": "13:45:00",
"duration": "2 days, 0:00:00",
"mixed_list": [
"3.0",
"0.0"
]
},
{
"strings": "c",
"bool": true,
"int": 3,
"float": 3.0,
"datetime": "2021-01-03 00:00:00",
"date": "2021-01-03",
"struct": {
"a": 5,
"b": 6
},
"list": [
5,
6
],
"array": [
3
],
"nulls": null,
"category": "mouse",
"set": "{5, 6}",
"imaginary": "(5+6j)",
"time": "14:15:00",
"duration": "3 days, 0:00:00",
"mixed_list": [
null,
"2021-01-01 00:00:00.000000"
]
}
]
8 changes: 4 additions & 4 deletions tests/_plugins/ui/_impl/tables/snapshots/pandas.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
strings,bool,int,float,datetime,date,struct,list,nulls,category,set,imaginary,time,duration,mixed_list,bytes
a,True,1,1.0,2021-01-01,2021-01-01,"{'a': 1, 'b': 2}","[1, 2]",,cat,"{1, 2}",(1+2j),12:30:00,1 days,"[1, 'two']",b'\x00\x00\x00\x00\x01\xc0U\xe8\xb1n1\xc0T@D\xf1?Bc\x95\x83'
b,False,2,2.0,2021-01-02,2021-01-02,"{'a': 3, 'b': 4}","[3, 4]",data,dog,"{3, 4}",(3+4j),13:45:00,2 days,"[3.0, False]",b'world'
c,True,3,3.0,2021-01-03,2021-01-03,"{'a': 5, 'b': 6}","[5, 6]",,mouse,"{5, 6}",(5+6j),14:15:00,3 days,"[None, datetime.datetime(2021, 1, 1, 0, 0)]",b'bytes'
strings,bool,int,float,datetime,date,nanosecond,datetime_index,period_range,interval_range,delta,none,infs,struct,list,nulls,category,set,imaginary,time,duration,mixed_list,bytes
a,True,1,1.0,2021-01-01,2021-01-01,2017-03-22 15:16:45,"DatetimeIndex(['1960-01-02', '1960-01-03', '1960-01-04'], dtype='datetime64[ns]', freq=None)",2017Q1,"(2017-01-01 00:00:00, 2017-01-02 00:00:00]","TimedeltaIndex(['1 days 06:05:01.000030'], dtype='timedelta64[ns]', freq=None)",,inf,"{'a': 1, 'b': 2}","[1, 2]",,cat,"{1, 2}",(1+2j),12:30:00,1 days,"[1, 'two']",b'\x00\x00\x00\x00\x01\xc0U\xe8\xb1n1\xc0T@D\xf1?Bc\x95\x83'
b,False,2,2.0,2021-01-02,2021-01-02,2017-07-14 02:40:00,"DatetimeIndex(['1970-01-02', '1970-01-03', '1970-01-04'], dtype='datetime64[ns]', freq=None)",2017Q2,"(2017-01-02 00:00:00, 2017-01-03 00:00:00]","TimedeltaIndex(['1 days 06:05:01.000030', '0 days 00:00:00.000015500'], dtype='timedelta64[ns]', freq=None)",,inf,"{'a': 3, 'b': 4}","[3, 4]",data,dog,"{3, 4}",(3+4j),13:45:00,2 days,"[3.0, False]",b'world'
c,True,3,3.0,2021-01-03,2021-01-03,2017-11-06 20:26:40,"DatetimeIndex(['1970-01-02', '1970-01-03', '1970-01-04'], dtype='datetime64[ns]', freq=None)",2017Q3,"(2017-01-03 00:00:00, 2017-01-04 00:00:00]","TimedeltaIndex(['1 days 06:05:01.000030', '0 days 00:00:00.000015500', NaT], dtype='timedelta64[ns]', freq=None)",,-inf,"{'a': 5, 'b': 6}","[5, 6]",,mouse,"{5, 6}",(5+6j),14:15:00,3 days,"[None, datetime.datetime(2021, 1, 1, 0, 0)]",b'bytes'
49 changes: 49 additions & 0 deletions tests/_plugins/ui/_impl/tables/snapshots/pandas.field_types.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,55 @@
"object"
]
],
[
"nanosecond",
[
"datetime",
"datetime64[ns]"
]
],
[
"datetime_index",
[
"string",
"object"
]
],
[
"period_range",
[
"unknown",
"period[Q-DEC]"
]
],
[
"interval_range",
[
"string",
"interval[datetime64[ns], right]"
]
],
[
"delta",
[
"string",
"object"
]
],
[
"none",
[
"string",
"object"
]
],
[
"infs",
[
"number",
"float64"
]
],
[
"struct",
[
Expand Down
Loading
Loading