Skip to content

Commit 916e156

Browse files
feat(python): Allow bare .row() on a single-row DataFrame, equivalent to .item() on a single-element DataFrame
1 parent a3474bb commit 916e156

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

py-polars/src/polars/dataframe/frame.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,9 +1683,8 @@ def item(self, row: int | None = None, column: int | str | None = None) -> Any:
16831683
if row is None and column is None:
16841684
if self.shape != (1, 1):
16851685
msg = (
1686-
"can only call `.item()` if the dataframe is of shape (1, 1),"
1687-
" or if explicit row/col values are provided;"
1688-
f" frame has shape {self.shape!r}"
1686+
'can only call `.item()` without "row" or "column" values if the '
1687+
f"DataFrame has a single element; shape={self.shape!r}"
16891688
)
16901689
raise ValueError(msg)
16911690
return self._df.to_series(0).get_index(0)
@@ -11450,7 +11449,16 @@ def row(
1145011449
>>> df.row(by_predicate=(pl.col("ham") == "b"))
1145111450
(2, 7, 'b')
1145211451
"""
11453-
if index is not None and by_predicate is not None:
11452+
if index is None and by_predicate is None:
11453+
if self.height == 1:
11454+
index = 0
11455+
else:
11456+
msg = (
11457+
'can only call `.row()` without "index" or "by_predicate" values '
11458+
f"if the DataFrame has a single row; shape={self.shape!r}"
11459+
)
11460+
raise ValueError(msg)
11461+
elif index is not None and by_predicate is not None:
1145411462
msg = "cannot set both 'index' and 'by_predicate'; mutually exclusive"
1145511463
raise ValueError(msg)
1145611464
elif isinstance(index, pl.Expr):

py-polars/tests/unit/dataframe/test_item.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@ def test_df_item() -> None:
1212

1313
def test_df_item_empty() -> None:
1414
df = pl.DataFrame()
15-
with pytest.raises(ValueError, match=r".* frame has shape \(0, 0\)"):
15+
with pytest.raises(ValueError, match=r".* shape=\(0, 0\)"):
1616
df.item()
1717

1818

1919
def test_df_item_incorrect_shape_rows() -> None:
2020
df = pl.DataFrame({"a": [1, 2]})
21-
with pytest.raises(ValueError, match=r".* frame has shape \(2, 1\)"):
21+
with pytest.raises(ValueError, match=r".* shape=\(2, 1\)"):
2222
df.item()
2323

2424

2525
def test_df_item_incorrect_shape_columns() -> None:
2626
df = pl.DataFrame({"a": [1], "b": [2]})
27-
with pytest.raises(ValueError, match=r".* frame has shape \(1, 2\)"):
27+
with pytest.raises(ValueError, match=r".* shape=\(1, 2\)"):
2828
df.item()
2929

3030

py-polars/tests/unit/test_rows.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,18 @@ def test_physical_row_encoding() -> None:
255255
"files": ["AGG_202307.xlsx"],
256256
}
257257
]
258+
259+
260+
def test_row_with_no_arguments() -> None:
261+
# confirm that calling bare `.row()` on a single-row frame behaves
262+
# consistently with calling `item()` on a single element frame
263+
df = pl.DataFrame({"tag": ["xx"], "n": [1]})
264+
assert df.row() == ("xx", 1)
265+
266+
# however, cannot call bare '.row()' if the frame does NOT have a single row
267+
df = pl.DataFrame({"tag": ["xx", "yy"], "n": [1, 2]})
268+
with pytest.raises(
269+
ValueError,
270+
match=r'can only call `\.row\(\)` without "index" or "by_predicate"',
271+
):
272+
df.row()

0 commit comments

Comments
 (0)