NumCpp  2.12.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
deleteIndices.hpp
Go to the documentation of this file.
1
28#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
40namespace 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(), PointerPolicy::SHELL), 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:139
size_type size() const noexcept
Definition: NdArrayCore.hpp:4524
size_type numCols() const noexcept
Definition: NdArrayCore.hpp:3465
size_type numRows() const noexcept
Definition: NdArrayCore.hpp:3477
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 > deleteRowIndices(const NdArray< dtype > &inArray, Indices inIndices)
Definition: deleteIndices.hpp:95
NdArray< dtype > deleteFlatIndices(const NdArray< dtype > &inArray, Indices inIndices)
Definition: deleteIndices.hpp:53
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:225
Definition: Cartesian.hpp:40
NdArray< dtype > deleteIndices(const NdArray< dtype > &inArray, int32 inIndex, Axis inAxis=Axis::NONE)
Definition: deleteIndices.hpp:311
Axis
Enum To describe an axis.
Definition: Enums.hpp:36
NdArray< dtype > unique(const NdArray< dtype > &inArray)
Definition: unique.hpp:53
std::int32_t int32
Definition: Types.hpp:36
std::uint32_t uint32
Definition: Types.hpp:40