NumCpp  2.10.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
deleteIndices.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <string>
31 #include <vector>
32 
35 #include "NumCpp/Core/Shape.hpp"
36 #include "NumCpp/Core/Slice.hpp"
38 #include "NumCpp/NdArray.hpp"
39 
40 namespace nc
41 {
42  namespace detail
43  {
44  //============================================================================
45  // Method Description:
52  template<typename dtype, typename Indices, type_traits::ndarray_int_concept<Indices> = 0>
53  NdArray<dtype> deleteFlatIndices(const NdArray<dtype>& inArray, Indices inIndices)
54  {
55  if constexpr (type_traits::is_ndarray_signed_int_v<Indices>)
56  {
57  const auto arraySize = inArray.size();
58  stl_algorithms::for_each(inIndices.begin(),
59  inIndices.end(),
60  [arraySize](auto& value)
61  {
62  if (value < 0)
63  {
64  value += arraySize;
65  }
66  });
67  }
68 
69  auto indices = unique(inIndices);
70 
71  std::vector<dtype> values;
72  values.reserve(indices.size());
73  for (int32 i = 0; i < static_cast<int32>(inArray.size()); ++i)
74  {
75  if (std::binary_search(indices.begin(), indices.end(), i))
76  {
77  continue;
78  }
79 
80  values.push_back(inArray[i]);
81  }
82 
83  return NdArray<dtype>(values);
84  }
85 
86  //============================================================================
87  // Method Description:
94  template<typename dtype, typename Indices, type_traits::ndarray_int_concept<Indices> = 0>
95  NdArray<dtype> deleteRowIndices(const NdArray<dtype>& inArray, Indices inIndices)
96  {
97  const auto arrayRows = static_cast<int32>(inArray.numRows());
98  if constexpr (type_traits::is_ndarray_signed_int_v<Indices>)
99  {
100  stl_algorithms::for_each(inIndices.begin(),
101  inIndices.end(),
102  [arrayRows](auto& value)
103  {
104  if (value < 0)
105  {
106  value += arrayRows;
107  }
108  });
109  }
110 
111  auto indices = unique(inIndices);
112 
113  uint32 indicesSize = 0;
114  std::for_each(indices.begin(),
115  indices.end(),
116  [arrayRows, &indicesSize](const auto& value)
117  {
118  if constexpr (std::is_signed_v<decltype(value)>)
119  {
120  if (value >= 0 && value < arrayRows)
121  {
122  ++indicesSize;
123  }
124  }
125  else
126  {
127  if (value < arrayRows)
128  {
129  ++indicesSize;
130  }
131  }
132  });
133 
134  const auto arrayCols = static_cast<int32>(inArray.numCols());
135  NdArray<dtype> returnArray(arrayRows - indicesSize, arrayCols);
136 
137  uint32 rowCounter = 0;
138  for (int32 row = 0; row < arrayRows; ++row)
139  {
140  if (std::binary_search(indices.begin(), indices.end(), row))
141  {
142  continue;
143  }
144 
145  for (int32 col = 0; col < arrayCols; ++col)
146  {
147  returnArray(rowCounter, col) = inArray(row, col);
148  }
149 
150  ++rowCounter;
151  }
152 
153  return returnArray;
154  }
155 
156  //============================================================================
157  // Method Description:
164  template<typename dtype, typename Indices, type_traits::ndarray_int_concept<Indices> = 0>
165  NdArray<dtype> deleteColumnIndices(const NdArray<dtype>& inArray, Indices inIndices)
166  {
167  const auto arrayCols = static_cast<int32>(inArray.numCols());
168  if constexpr (type_traits::is_ndarray_signed_int_v<Indices>)
169  {
170  stl_algorithms::for_each(inIndices.begin(),
171  inIndices.end(),
172  [arrayCols](auto& value)
173  {
174  if (value < 0)
175  {
176  value += arrayCols;
177  }
178  });
179  }
180 
181  auto indices = unique(inIndices);
182 
183  uint32 indicesSize = 0;
184  std::for_each(indices.begin(),
185  indices.end(),
186  [arrayCols, &indicesSize](const auto& value)
187  {
188  if constexpr (std::is_signed_v<decltype(value)>)
189  {
190  if (value >= 0 && value < arrayCols)
191  {
192  ++indicesSize;
193  }
194  }
195  else
196  {
197  if (value < arrayCols)
198  {
199  ++indicesSize;
200  }
201  }
202  });
203 
204  const auto arrayRows = static_cast<int32>(inArray.numRows());
205  NdArray<dtype> returnArray(arrayRows, arrayCols - indicesSize);
206 
207  uint32 colCounter = 0;
208  for (int32 col = 0; col < arrayCols; ++col)
209  {
210  if (std::binary_search(indices.begin(), indices.end(), col))
211  {
212  continue;
213  }
214 
215  for (int32 row = 0; row < arrayRows; ++row)
216  {
217  returnArray(row, colCounter) = inArray(row, col);
218  }
219 
220  ++colCounter;
221  }
222 
223  return returnArray;
224  }
225  } // namespace detail
226 
227  //============================================================================
228  // Method Description:
236  template<typename dtype, typename Indices, type_traits::ndarray_int_concept<Indices> = 0>
237  NdArray<dtype> deleteIndices(const NdArray<dtype>& inArray, const Indices& inIndices, Axis inAxis = Axis::NONE)
238  {
239  switch (inAxis)
240  {
241  case Axis::NONE:
242  {
243  return detail::deleteFlatIndices(inArray, inIndices);
244  }
245  case Axis::ROW:
246  {
247  return detail::deleteRowIndices(inArray, inIndices);
248  }
249  case Axis::COL:
250  {
251  return detail::deleteColumnIndices(inArray, inIndices);
252  }
253  default:
254  {
255  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
256  return {}; // get rid of compiler warning
257  }
258  }
259  }
260 
261  //============================================================================
262  // Method Description:
270  template<typename dtype>
271  NdArray<dtype> deleteIndices(const NdArray<dtype>& inArray, Slice inIndicesSlice, Axis inAxis = Axis::NONE)
272  {
273  switch (inAxis)
274  {
275  case Axis::NONE:
276  {
277  inIndicesSlice.makePositiveAndValidate(inArray.size());
278  break;
279  }
280  case Axis::ROW:
281  {
282  inIndicesSlice.makePositiveAndValidate(inArray.numRows());
283  break;
284  }
285  case Axis::COL:
286  {
287  inIndicesSlice.makePositiveAndValidate(inArray.numCols());
288  break;
289  }
290  }
291 
292  std::vector<int32> indices;
293  for (auto i = inIndicesSlice.start; i < inIndicesSlice.stop; i += inIndicesSlice.step)
294  {
295  indices.push_back(i);
296  }
297 
298  return deleteIndices(inArray, NdArray<int32>(indices.data(), indices.size(), false), inAxis);
299  }
300 
301  //============================================================================
302  // Method Description:
310  template<typename dtype>
311  NdArray<dtype> deleteIndices(const NdArray<dtype>& inArray, int32 inIndex, Axis inAxis = Axis::NONE)
312  {
313  NdArray<int32> inIndices = { inIndex };
314  return deleteIndices(inArray, inIndices, inAxis);
315  }
316 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:138
size_type size() const noexcept
Definition: NdArrayCore.hpp:4415
size_type numCols() const noexcept
Definition: NdArrayCore.hpp:3388
size_type numRows() const noexcept
Definition: NdArrayCore.hpp:3400
A Class for slicing into NdArrays.
Definition: Slice.hpp:45
int32 step
Definition: Slice.hpp:50
int32 start
Definition: Slice.hpp:48
void makePositiveAndValidate(uint32 inArraySize)
Definition: Slice.hpp:142
int32 stop
Definition: Slice.hpp:49
NdArray< dtype > deleteColumnIndices(const NdArray< dtype > &inArray, Indices inIndices)
Definition: deleteIndices.hpp:165
NdArray< dtype > deleteFlatIndices(const NdArray< dtype > &inArray, Indices inIndices)
Definition: deleteIndices.hpp:53
NdArray< dtype > deleteRowIndices(const NdArray< dtype > &inArray, Indices inIndices)
Definition: deleteIndices.hpp:95
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:225
Definition: Coordinate.hpp:45
NdArray< dtype > deleteIndices(const NdArray< dtype > &inArray, int32 inIndex, Axis inAxis=Axis::NONE)
Definition: deleteIndices.hpp:311
Axis
Enum To describe an axis.
Definition: Types.hpp:47
std::int32_t int32
Definition: Types.hpp:36
NdArray< dtype > unique(const NdArray< dtype > &inArray)
Definition: unique.hpp:53
std::uint32_t uint32
Definition: Types.hpp:40