Skip to content

Commit

Permalink
Rename measure_* columns to measures_* in as_pandas (#396)
Browse files Browse the repository at this point in the history
## Description

<!-- Provide a brief description of the PR's purpose here. -->

In other parts of the library, fields like `solution` and `objective`
are consistently plural or singular. Since the rest of the library uses
`measures` (e.g., EliteBatch has `measures_batch`), this PR changes the
columns in `as_pandas` to start with `measures` instead of `measure`.

## TODO

<!-- Notable points that this PR has either accomplished or will
accomplish. -->

## Questions

<!-- Any concerns or points of confusion? -->

## Status

- [x] I have read the guidelines in

[CONTRIBUTING.md](https://github.com/icaros-usc/pyribs/blob/master/CONTRIBUTING.md)
- [x] I have formatted my code using `yapf`
- [x] I have tested my code by running `pytest`
- [x] I have linted my code with `pylint`
- [x] I have added a one-line description of my change to the changelog
in
      `HISTORY.md`
- [x] This PR is ready to go
  • Loading branch information
btjanaka committed Nov 1, 2023
1 parent e9cbecd commit 9484717
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 26 deletions.
4 changes: 3 additions & 1 deletion HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

#### API

- Add GradientOperatorEmitter to support OMG-MEGA and OG-MAP-Elites ({pr}`348`)
- **Backwards-incompatible:** Rename `measure_*` columns to `measures_*` in
`as_pandas` ({pr}`396`)
- Add ArrayStore data structure ({pr}`395`)
- Add GradientOperatorEmitter to support OMG-MEGA and OG-MAP-Elites ({pr}`348`)

#### Improvements

Expand Down
16 changes: 8 additions & 8 deletions ribs/archives/_archive_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1017,20 +1017,20 @@ def as_pandas(self, include_solutions=True, include_metadata=False):
- 1 column of integers (``np.int32``) for the index, named ``index``.
See :meth:`index_of` for more info.
- :attr:`measure_dim` columns for the measures, named ``measure_0,
measure_1, ...``
- :attr:`measure_dim` columns for the measures, named ``measures_0,
measures_1, ...``
- 1 column for the objectives, named ``objective``
- :attr:`solution_dim` columns for the solution parameters, named
``solution_0, solution_1, ...``
- 1 column for the metadata objects, named ``metadata``
In short, the dataframe looks like this:
+-------+------------+------+------------+-------------+-----+----------+
| index | measure_0 | ... | objective | solution_0 | ... | metadata |
+=======+============+======+============+=============+=====+==========+
| | | ... | | | ... | |
+-------+------------+------+------------+-------------+-----+----------+
+-------+------------+------+-----------+------------+-----+----------+
| index | measures_0 | ... | objective | solution_0 | ... | metadata |
+=======+============+======+===========+============+=====+==========+
| | | ... | | | ... | |
+-------+------------+------+-----------+------------+-----+----------+
Compared to :class:`pandas.DataFrame`, the :class:`ArchiveDataFrame`
adds methods and attributes which make it easier to manipulate archive
Expand All @@ -1054,7 +1054,7 @@ def as_pandas(self, include_solutions=True, include_metadata=False):

measures_batch = self._measures_arr[indices]
for i in range(self._measure_dim):
data[f"measure_{i}"] = measures_batch[:, i]
data[f"measures_{i}"] = measures_batch[:, i]

data["objective"] = self._objective_arr[indices]

Expand Down
2 changes: 1 addition & 1 deletion ribs/archives/_archive_data_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def measures_batch(self):
Returns:
(n, measure_dim) numpy.ndarray: See above.
"""
cols = [c for c in self if c.startswith("measure_")]
cols = [c for c in self if c.startswith("measures_")]
return self[cols].to_numpy(copy=True) if cols else None

def index_batch(self):
Expand Down
4 changes: 2 additions & 2 deletions tests/archives/archive_base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ def test_as_pandas(name, with_elite, include_solutions, include_metadata,
data = get_archive_data(name, dtype)

# Set up expected columns and data types.
measure_cols = [f"measure_{i}" for i in range(len(data.measures))]
measure_cols = [f"measures_{i}" for i in range(len(data.measures))]
expected_cols = ["index"] + measure_cols + ["objective"]
expected_dtypes = [np.int32, *[dtype for _ in measure_cols], dtype]
if include_solutions:
Expand Down Expand Up @@ -432,4 +432,4 @@ def test_as_pandas(name, with_elite, include_solutions, include_metadata,
expected_data += list(data.solution)
if include_metadata:
expected_data.append(data.metadata)
assert (df.loc[0, "measure_0":] == expected_data).all()
assert (df.loc[0, "measures_0":] == expected_data).all()
6 changes: 3 additions & 3 deletions tests/archives/archive_data_frame_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def df(data):
return ArchiveDataFrame({
"index": index_batch,
"objective": objective_batch,
"measure_0": measures_batch[:, 0],
"measures_0": measures_batch[:, 0],
"solution_0": solution_batch[:, 0],
"metadata": metadata_batch,
})
Expand Down Expand Up @@ -55,7 +55,7 @@ def test_batch_methods(data, df):

@pytest.mark.parametrize(
"remove",
["index", "objective", "measure_0", "metadata", "solution_0"],
["index", "objective", "measures_0", "metadata", "solution_0"],
ids=["index", "objective", "measures", "metadata", "solutions"],
)
def test_batch_methods_can_be_none(df, remove):
Expand All @@ -65,7 +65,7 @@ def test_batch_methods_can_be_none(df, remove):
method = {
"solution_0": df.solution_batch,
"objective": df.objective_batch,
"measure_0": df.measures_batch,
"measures_0": df.measures_batch,
"index": df.index_batch,
"metadata": df.metadata_batch,
}[remove]
Expand Down
2 changes: 1 addition & 1 deletion tests/archives/sliding_boundaries_archive_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def test_initial_remap():

# Check that all the measures are as expected.
pandas_measures = archive.as_pandas(include_solutions=False)[[
"measure_0", "measure_1"
"measures_0", "measures_1"
]]
measures = list(pandas_measures.itertuples(name=None, index=False))
assert np.isclose(sorted(measures), sorted(expected_measures)).all()
Expand Down
20 changes: 10 additions & 10 deletions tutorials/tom_cruise_dqd.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -929,22 +929,22 @@
"\n",
"# Compute the min and max measures for which solutions were found.\n",
"measure_bounds = [\n",
" (round(df['measure_0'].min(), 2), round(df['measure_0'].max(), 2)),\n",
" (round(df['measure_1'].min(), 2), round(df['measure_1'].max(), 2)),\n",
" (round(df['measures_0'].min(), 2), round(df['measures_0'].max(), 2)),\n",
" (round(df['measures_1'].min(), 2), round(df['measures_1'].max(), 2)),\n",
"]\n",
"delta_measure_0 = round((measure_bounds[0][1] - measure_bounds[0][0])/img_freq[0], 2)\n",
"delta_measure_1 = round((measure_bounds[1][1] - measure_bounds[1][0])/img_freq[1], 2)\n",
"delta_measures_0 = round((measure_bounds[0][1] - measure_bounds[0][0])/img_freq[0], 2)\n",
"delta_measures_1 = round((measure_bounds[1][1] - measure_bounds[1][0])/img_freq[1], 2)\n",
"\n",
"for col, row in itertools.product(range(img_freq[1]), range(img_freq[0])):\n",
" # Compute bounds of a box in measure space.\n",
" measure_0_low = round(measure_bounds[0][0] + delta_measure_0*row, 2)\n",
" measure_0_high = round(measure_bounds[0][0] + delta_measure_0*(row+1), 2)\n",
" measure_1_low = round(measure_bounds[1][0] + delta_measure_1*col, 2)\n",
" measure_1_high = round(measure_bounds[1][0] + delta_measure_1*(col+1), 2)\n",
" measures_0_low = round(measure_bounds[0][0] + delta_measures_0*row, 2)\n",
" measures_0_high = round(measure_bounds[0][0] + delta_measures_0*(row+1), 2)\n",
" measures_1_low = round(measure_bounds[1][0] + delta_measures_1*col, 2)\n",
" measures_1_high = round(measure_bounds[1][0] + delta_measures_1*(col+1), 2)\n",
"\n",
" # Query for a solution with measures within this box.\n",
" query_string = (f\"{measure_0_low} <= measure_0 & measure_0 <= {measure_0_high} & \"\n",
" f\"{measure_1_low} <= measure_1 & measure_1 <= {measure_1_high}\")\n",
" query_string = (f\"{measures_0_low} <= measures_0 & measures_0 <= {measures_0_high} & \"\n",
" f\"{measures_1_low} <= measures_1 & measures_1 <= {measures_1_high}\")\n",
" df_box = df.query(query_string)\n",
"\n",
" if not df_box.empty:\n",
Expand Down

0 comments on commit 9484717

Please sign in to comment.