diff --git a/dimod/sampleset.py b/dimod/sampleset.py
index 87179821..250bcd90 100644
--- a/dimod/sampleset.py
+++ b/dimod/sampleset.py
@@ -559,6 +559,32 @@ class SampleSet(abc.Iterable, abc.Sized):
     # Properties
     ###############################################################################################
 
+    @property
+    def data_vectors(self):
+        """The per-sample data in a vector.
+
+        Returns:
+            dict: A dict where the keys are the fields in the record and the
+            values are the corresponding arrays.
+
+        Examples:
+            >>> sampleset = dimod.SampleSet.from_samples([[-1, 1], [1, 1]], dimod.SPIN,
+                                                         energy=[-1, 1])
+            >>> sampleset.data_vectors['energy']
+            array([-1,  1])
+
+            Note that this is equivalent to, and less performant than:
+
+            >>> sampleset = dimod.SampleSet.from_samples([[-1, 1], [1, 1]], dimod.SPIN,
+                                                         energy=[-1, 1])
+            >>> sampleset.record['energy']
+            array([-1,  1])
+
+
+        """
+        return {field: self.record[field] for field in self.record.dtype.names
+                if field != 'sample'}
+
     @property
     def first(self):
         """Sample with the lowest-energy.

`SampleSet.data_vectors` or similar
The `Reponse` object included an attribute `Response.data_vectors` that was deprecated and then removed. However, it seems that this was a very useful feature that a lot of users used.

*Additional Context*
It was originally removed because we changed the way we stored data vectors from a dict-of-lists to a numpy structured array and this format was less performant.
diff --git a/tests/test_sampleset.py b/tests/test_sampleset.py
index a36a6b2c..2818f77d 100644
--- a/tests/test_sampleset.py
+++ b/tests/test_sampleset.py
@@ -31,6 +31,7 @@ except ImportError:
 
 
 class Test_as_samples(unittest.TestCase):
+    # tests for as_samples function
 
     def test_copy_false(self):
         samples_like = np.ones((5, 5))
@@ -126,7 +127,7 @@ class Test_as_samples(unittest.TestCase):
         self.assertEqual(arr.dtype, np.int32)
 
 
-class TestSampleSet(unittest.TestCase):
+class TestConstruction(unittest.TestCase):
     def test_from_samples(self):
 
         nv = 5
@@ -197,17 +198,6 @@ class TestSampleSet(unittest.TestCase):
         with self.assertRaises(ValueError):
             dimod.SampleSet.from_samples(np.ones((3, 5)), dimod.SPIN, energy=[5, 5])
 
-    def test_eq_ordered(self):
-        # samplesets should be equal regardless of variable order
-        ss0 = dimod.SampleSet.from_samples(([-1, 1], 'ab'), dimod.SPIN, energy=0.0)
-        ss1 = dimod.SampleSet.from_samples(([1, -1], 'ba'), dimod.SPIN, energy=0.0)
-        ss2 = dimod.SampleSet.from_samples(([1, -1], 'ab'), dimod.SPIN, energy=0.0)
-        ss3 = dimod.SampleSet.from_samples(([1, -1], 'ac'), dimod.SPIN, energy=0.0)
-
-        self.assertEqual(ss0, ss1)
-        self.assertNotEqual(ss0, ss2)
-        self.assertNotEqual(ss1, ss3)
-
     def test_shorter_samples(self):
         ss = dimod.SampleSet.from_samples(np.ones((100, 5), dtype='int8'), dimod.BINARY, energy=np.ones(100))
 
@@ -225,6 +215,27 @@ class TestSampleSet(unittest.TestCase):
         self.assertEqual(samples.aggregate(),
                          dimod.SampleSet.from_samples(([-1, 1], 'ab'), dimod.SPIN, energy=0.0, num_occurrences=2))
 
+    def test_from_bqm_single_sample(self):
+        bqm = dimod.BinaryQuadraticModel.from_ising({}, {'ab': -1})
+        samples = dimod.SampleSet.from_samples_bqm({'a': -1, 'b': 1}, bqm)
+        self.assertEqual(samples,
+                         dimod.SampleSet.from_samples(([-1, 1], 'ab'), dimod.SPIN, energy=1))
+
+
+class TestEq(unittest.TestCase):
+    def test_ordered(self):
+        # samplesets should be equal regardless of variable order
+        ss0 = dimod.SampleSet.from_samples(([-1, 1], 'ab'), dimod.SPIN, energy=0.0)
+        ss1 = dimod.SampleSet.from_samples(([1, -1], 'ba'), dimod.SPIN, energy=0.0)
+        ss2 = dimod.SampleSet.from_samples(([1, -1], 'ab'), dimod.SPIN, energy=0.0)
+        ss3 = dimod.SampleSet.from_samples(([1, -1], 'ac'), dimod.SPIN, energy=0.0)
+
+        self.assertEqual(ss0, ss1)
+        self.assertNotEqual(ss0, ss2)
+        self.assertNotEqual(ss1, ss3)
+
+
+class TestAggregate(unittest.TestCase):
     def test_aggregate_simple(self):
         samples = dimod.SampleSet.from_samples(([[-1, 1], [-1, 1]], 'ab'), dimod.SPIN, energy=[0.0, 0.0])
 
@@ -235,13 +246,9 @@ class TestSampleSet(unittest.TestCase):
         self.assertEqual(samples,
                          dimod.SampleSet.from_samples(([[-1, 1], [-1, 1]], 'ab'), dimod.SPIN, energy=[0.0, 0.0]))
 
-    def test_from_bqm_single_sample(self):
-        bqm = dimod.BinaryQuadraticModel.from_ising({}, {'ab': -1})
-        samples = dimod.SampleSet.from_samples_bqm({'a': -1, 'b': 1}, bqm)
-        self.assertEqual(samples,
-                         dimod.SampleSet.from_samples(([-1, 1], 'ab'), dimod.SPIN, energy=1))
 
-    def test_truncate(self):
+class TestTruncate(unittest.TestCase):
+    def test_typical(self):
         bqm = dimod.BinaryQuadraticModel.from_ising({v: -1 for v in range(100)}, {})
         samples = dimod.SampleSet.from_samples_bqm(np.tril(np.ones(100)), bqm.binary)
 
@@ -255,7 +262,7 @@ class TestSampleSet(unittest.TestCase):
                 else:
                     self.assertEqual(val, 1)
 
-    def test_truncate_unordered(self):
+    def test_unordered(self):
         bqm = dimod.BinaryQuadraticModel.from_ising({v: -1 for v in range(100)}, {})
         samples = dimod.SampleSet.from_samples_bqm(np.triu(np.ones(100)), bqm.binary)
 
@@ -270,7 +277,7 @@ class TestSampleSet(unittest.TestCase):
                     self.assertEqual(val, 1)
 
 
-class TestSampleSetIteration(unittest.TestCase):
+class TestIteration(unittest.TestCase):
     def test_data_reverse(self):
         bqm = dimod.BinaryQuadraticModel.from_ising({}, {'ab': -1})
         sampleset = dimod.SampleSet.from_samples_bqm([{'a': -1, 'b': 1}, {'a': 1, 'b': 1}], bqm)
@@ -280,8 +287,7 @@ class TestSampleSetIteration(unittest.TestCase):
         self.assertEqual(samples, list(reversed(reversed_samples)))
 
 
-class TestSampleSetSerialization(unittest.TestCase):
-
+class TestSerialization(unittest.TestCase):
     def test_functional_simple_shapes(self):
         for ns in range(1, 9):
             for nv in range(1, 15):
@@ -324,7 +330,7 @@ class TestSampleSetSerialization(unittest.TestCase):
 
 
 @unittest.skipUnless(_pandas, "no pandas present")
-class TestSampleSet_to_pandas_dataframe(unittest.TestCase):
+class TestPandas(unittest.TestCase):
     def test_simple(self):
         samples = dimod.SampleSet.from_samples(([[-1, 1, -1], [-1, -1, 1]], 'abc'),
                                                dimod.SPIN, energy=[-.5, .5])
@@ -347,12 +353,31 @@ class TestSampleSet_to_pandas_dataframe(unittest.TestCase):
         pd.testing.assert_frame_equal(df, other, check_dtype=False)
 
 
-class TestSampleSet_first(unittest.TestCase):
+class TestFirst(unittest.TestCase):
+    # SampleSet.first property
     def test_empty(self):
         with self.assertRaises(ValueError):
             dimod.SampleSet.from_samples([], dimod.SPIN, energy=[]).first
 
 
+class TestDataVectors(unittest.TestCase):
+    # SampleSet.data_vectors property
+    def test_empty(self):
+        ss = dimod.SampleSet.from_samples([], dimod.SPIN, energy=[])
+
+        self.assertEqual(set(ss.data_vectors), {'energy', 'num_occurrences'})
+        for field, vector in ss.data_vectors.items():
+            np.testing.assert_array_equal(vector, [])
+
+    def test_view(self):
+        # make sure that the vectors are views
+        ss = dimod.SampleSet.from_samples([[-1, 1], [1, 1]], dimod.SPIN, energy=[5, 5])
+
+        self.assertEqual(set(ss.data_vectors), {'energy', 'num_occurrences'})
+        for field, vector in ss.data_vectors.items():
+            np.shares_memory(vector, ss.record)
+
+
 class Test_concatenate(unittest.TestCase):
     def test_simple(self):
         ss0 = dimod.SampleSet.from_samples([-1, +1], dimod.SPIN, energy=-1)

pip install -e .[all]
parse_log_pytest
requirements.txt
pytest coverage codecov
apt-get update apt-get install -y libboost-dev
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
charset-normalizer==2.0.12
codecov==2.1.13
coverage==6.2
Cython==3.0.12
decorator==5.1.1
-e git+https://github.com/dwavesystems/dimod.git@4bdd07c68b6d6b127e21266a8920c644ccbc405d#egg=dimod
idna==3.10
importlib-metadata==4.8.3
iniconfig==1.1.1
jsonschema==2.6.0
mock==2.0.0
networkx==2.0
numpy==1.15.0
packaging==21.3
pandas==0.22.0
pbr==6.1.1
pluggy==1.0.0
py==1.11.0
pymongo==3.7.1
pyparsing==3.1.4
pytest==7.0.1
python-dateutil==2.9.0.post0
pytz==2025.2
requests==2.27.1
six==1.11.0
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.26.20
zipp==3.6.0

name: dimod
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - charset-normalizer==2.0.12
      - codecov==2.1.13
      - coverage==6.2
      - cython==3.0.12
      - decorator==5.1.1
      - idna==3.10
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - jsonschema==2.6.0
      - mock==2.0.0
      - networkx==2.0
      - numpy==1.15.0
      - packaging==21.3
      - pandas==0.22.0
      - pbr==6.1.1
      - pluggy==1.0.0
      - py==1.11.0
      - pymongo==3.7.1
      - pyparsing==3.1.4
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - requests==2.27.1
      - six==1.11.0
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - zipp==3.6.0
prefix: /opt/conda/envs/dimod

tests/test_sampleset.py::TestDataVectors::test_empty tests/test_sampleset.py::TestDataVectors::test_view
tests/test_sampleset.py::Test_as_samples::test_copy_false tests/test_sampleset.py::Test_as_samples::test_dict_with_inconsistent_labels tests/test_sampleset.py::Test_as_samples::test_dict_with_labels tests/test_sampleset.py::Test_as_samples::test_empty_dict tests/test_sampleset.py::Test_as_samples::test_empty_list tests/test_sampleset.py::Test_as_samples::test_empty_list_labelled tests/test_sampleset.py::Test_as_samples::test_empty_ndarray tests/test_sampleset.py::Test_as_samples::test_iterator tests/test_sampleset.py::Test_as_samples::test_iterator_labelled tests/test_sampleset.py::Test_as_samples::test_list_of_empty tests/test_sampleset.py::Test_as_samples::test_mixed_sampletype tests/test_sampleset.py::Test_as_samples::test_ndarray tests/test_sampleset.py::Test_as_samples::test_ndarray_labelled tests/test_sampleset.py::TestConstruction::test_from_bqm_single_sample tests/test_sampleset.py::TestConstruction::test_from_samples tests/test_sampleset.py::TestConstruction::test_from_samples_empty tests/test_sampleset.py::TestConstruction::test_from_samples_fields_multiple tests/test_sampleset.py::TestConstruction::test_from_samples_fields_single tests/test_sampleset.py::TestConstruction::test_from_samples_iterator tests/test_sampleset.py::TestConstruction::test_from_samples_single_sample tests/test_sampleset.py::TestConstruction::test_from_samples_str_labels tests/test_sampleset.py::TestConstruction::test_from_samples_with_aggregation tests/test_sampleset.py::TestConstruction::test_mismatched_shapes tests/test_sampleset.py::TestConstruction::test_shorter_samples tests/test_sampleset.py::TestEq::test_ordered tests/test_sampleset.py::TestAggregate::test_aggregate_simple tests/test_sampleset.py::TestTruncate::test_typical tests/test_sampleset.py::TestTruncate::test_unordered tests/test_sampleset.py::TestIteration::test_data_reverse tests/test_sampleset.py::TestSerialization::test_functional_json tests/test_sampleset.py::TestSerialization::test_functional_simple_shapes tests/test_sampleset.py::TestSerialization::test_functional_str tests/test_sampleset.py::TestPandas::test_sample_column tests/test_sampleset.py::TestPandas::test_simple tests/test_sampleset.py::TestFirst::test_empty tests/test_sampleset.py::Test_concatenate::test_empty tests/test_sampleset.py::Test_concatenate::test_simple tests/test_sampleset.py::Test_concatenate::test_variables_order tests/test_sampleset.py::Test_concatenate::test_variables_order_and_vartype
dimod/sampleset.py
dimod/sampleset.py