tamnd / tamnd/firepanda

df.columns, df.index and s.index cannot be assigned to

Open
#256 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Mojo
Stars
1
Forks
0
PR merge metrics
PR metrics pending

Description

Renaming every column in one line is one of the most common things anybody does to a pandas frame, and it does not work here.

```python
df.columns = ["x", "y"]
# AttributeError: property 'columns' of 'DataFrame' object has no setter
s.index = [9, 8]
# AttributeError: property 'index' of 'Series' object has no setter
```

Measured against the pinned pandas 3.0.3, all three of `DataFrame.columns`, `DataFrame.index` and `Series.index` accept an assignment, and a wrong length is a `ValueError` reading `Length mismatch: Expected axis has 2 elements, new values have 1 elements`.

This surfaced from the conformance suite in an indirect way that is worth writing down, because the label it arrived under made it look like a harness quibble and it is not. Seven L0 records fail with `'property', expected 'attribute'`. The suite classifies a member by asking whether the class attribute is an instance of the builtin `property`, and pandas' `columns` and `index` are `pandas._libs.properties.AxisProperty`, a Cython descriptor that is not one, so pandas is recorded as `attribute` and firepanda as `property`. That looks like the suite testing a CPython implementation detail.

The reason it is not is that the two kinds differ in the one way a user can feel. `AxisProperty` has a setter and a bare read only `property` does not, so the difference the suite is reporting is exactly this gap, seen through a vocabulary that does not have a word for it. The right fix is here rather than in the harness.

Seven names are affected. `DataFrame.columns`, `DataFrame.index` and `Series.index` are the ones that should take an assignment. `Index.dtype`, `Index.is_unique`, `Index.hasnans` and `Index.inferred_type` are `CachedProperty` in pandas and are read only there too, so those four are the harness vocabulary and not a gap, and they are worth separating out before anybody starts on this.

### What the setter has to do

Length is checked against the existing axis and a mismatch raises `ValueError` with pandas' wording above. Assigning to `DataFrame.columns` renames in place without touching any column data. Assigning to `DataFrame.index` or `Series.index` replaces the labels without reordering anything, which is the difference between this and `reindex` and is worth a test of its own, since getting it wrong quietly reorders a user's rows.

Related to [#254](https://github.com/tamnd/firepanda/issues/254), which is that `df.columns` answers with a Python list where pandas answers with an `Index`. These are separate but they touch the same accessor, and doing them together would mean one pass over the type rather than two.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.