Skip to content

Commit 28e0db5

Browse files
committed
Build C API DataFrames from Arrow
Use the native C API Arrow export as the pandas DataFrame source instead of C API row iteration, while preserving pandas-compatible dtype and nested object normalization.
1 parent 72f89f7 commit 28e0db5

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

src_py/_lbug_capi.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,10 +1407,28 @@ def getCSR(self, *_args: Any, **_kwargs: Any) -> Any:
14071407

14081408
def getAsDF(self) -> Any:
14091409
import pandas as pd
1410+
import pyarrow as pa
14101411

1411-
df = pd.DataFrame(
1412-
self._get_all_rows_from_start(), columns=self.getColumnNames()
1413-
)
1412+
def normalize_object_value(value: Any) -> Any:
1413+
if isinstance(value, dict):
1414+
return {key: normalize_object_value(val) for key, val in value.items()}
1415+
if isinstance(value, list):
1416+
if all(isinstance(item, tuple) and len(item) == 2 for item in value):
1417+
return {key: normalize_object_value(val) for key, val in value}
1418+
return [normalize_object_value(item) for item in value]
1419+
if hasattr(value, "tolist") and type(value).__module__.startswith("numpy"):
1420+
return normalize_object_value(value.tolist())
1421+
return value
1422+
1423+
table = self.getAsArrow(0, True)
1424+
try:
1425+
df = table.to_pandas()
1426+
except pa.ArrowNotImplementedError:
1427+
df = pd.DataFrame(
1428+
{name: table.column(name).to_pylist() for name in table.column_names}
1429+
)
1430+
for name in df.select_dtypes(include="object").columns:
1431+
df[name] = df[name].map(normalize_object_value)
14141432
for name, dtype in zip(
14151433
self.getColumnNames(), self.getColumnDataTypes(), strict=False
14161434
):
@@ -1449,7 +1467,7 @@ def getAsDF(self) -> Any:
14491467
)
14501468
df[name] = datetime_col.astype("datetime64[us]")
14511469
elif dtype == "INTERVAL":
1452-
df[name] = pd.to_timedelta(df[name])
1470+
df[name] = pd.to_timedelta(df[name]).astype("timedelta64[ns]")
14531471
elif dtype == "INT128":
14541472
df[name] = df[name].astype("float64")
14551473
return df

0 commit comments

Comments
 (0)