Skip to content

Commit fb81eea

Browse files
feat: Support df.info() with null index (#2094)
1 parent 999dd99 commit fb81eea

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

bigframes/core/blocks.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ def from_local(
252252
pass
253253
return block
254254

255+
@property
256+
def has_index(self) -> bool:
257+
return len(self._index_columns) > 0
258+
255259
@property
256260
def index(self) -> BlockIndexProperties:
257261
"""Row identities for values in the Block."""

bigframes/dataframe.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,6 @@ def memory_usage(self, index: bool = True):
489489
column_sizes = pandas.concat([index_size, column_sizes])
490490
return column_sizes
491491

492-
@validations.requires_index
493492
def info(
494493
self,
495494
verbose: Optional[bool] = None,
@@ -512,12 +511,17 @@ def info(
512511

513512
obuf.write(f"{type(self)}\n")
514513

515-
index_type = "MultiIndex" if self.index.nlevels > 1 else "Index"
514+
if self._block.has_index:
515+
index_type = "MultiIndex" if self.index.nlevels > 1 else "Index"
516516

517-
# These accessses are kind of expensive, maybe should try to skip?
518-
first_indice = self.index[0]
519-
last_indice = self.index[-1]
520-
obuf.write(f"{index_type}: {n_rows} entries, {first_indice} to {last_indice}\n")
517+
# These accessses are kind of expensive, maybe should try to skip?
518+
first_indice = self.index[0]
519+
last_indice = self.index[-1]
520+
obuf.write(
521+
f"{index_type}: {n_rows} entries, {first_indice} to {last_indice}\n"
522+
)
523+
else:
524+
obuf.write("NullIndex\n")
521525

522526
dtype_strings = self.dtypes.astype("string")
523527
if show_all_columns:

tests/system/small/test_null_index.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
# limitations under the License.
1414

1515

16+
import io
17+
1618
import pandas as pd
1719
import pytest
1820

@@ -44,6 +46,38 @@ def test_null_index_materialize(scalars_df_null_index, scalars_pandas_df_default
4446
)
4547

4648

49+
def test_null_index_info(scalars_df_null_index):
50+
expected = (
51+
"<class 'bigframes.dataframe.DataFrame'>\n"
52+
"NullIndex\n"
53+
"Data columns (total 14 columns):\n"
54+
" # Column Non-Null Count Dtype\n"
55+
"--- ------------- ---------------- ------------------------------\n"
56+
" 0 bool_col 8 non-null boolean\n"
57+
" 1 bytes_col 6 non-null binary[pyarrow]\n"
58+
" 2 date_col 7 non-null date32[day][pyarrow]\n"
59+
" 3 datetime_col 6 non-null timestamp[us][pyarrow]\n"
60+
" 4 geography_col 4 non-null geometry\n"
61+
" 5 int64_col 8 non-null Int64\n"
62+
" 6 int64_too 9 non-null Int64\n"
63+
" 7 numeric_col 6 non-null decimal128(38, 9)[pyarrow]\n"
64+
" 8 float64_col 7 non-null Float64\n"
65+
" 9 rowindex_2 9 non-null Int64\n"
66+
" 10 string_col 8 non-null string\n"
67+
" 11 time_col 6 non-null time64[us][pyarrow]\n"
68+
" 12 timestamp_col 6 non-null timestamp[us, tz=UTC][pyarrow]\n"
69+
" 13 duration_col 7 non-null duration[us][pyarrow]\n"
70+
"dtypes: Float64(1), Int64(3), binary[pyarrow](1), boolean(1), date32[day][pyarrow](1), decimal128(38, 9)[pyarrow](1), duration[us][pyarrow](1), geometry(1), string(1), time64[us][pyarrow](1), timestamp[us, tz=UTC][pyarrow](1), timestamp[us][pyarrow](1)\n"
71+
"memory usage: 1269 bytes\n"
72+
)
73+
74+
bf_result = io.StringIO()
75+
76+
scalars_df_null_index.drop(columns="rowindex").info(buf=bf_result)
77+
78+
assert expected == bf_result.getvalue()
79+
80+
4781
def test_null_index_series_repr(scalars_df_null_index, scalars_pandas_df_default_index):
4882
bf_result = scalars_df_null_index["int64_too"].head(5).__repr__()
4983
pd_result = (

0 commit comments

Comments
 (0)