0
# Sorting and Counting
1
2
Sorting algorithms, search operations, and counting functions for array organization and analysis. These functions provide comprehensive tools for ordering data, finding elements, and analyzing array contents with GPU acceleration.
3
4
## Capabilities
5
6
### Sorting Functions
7
8
Functions for sorting array elements in various ways.
9
10
```python { .api }
11
def sort(a, axis=-1, kind=None, order=None):
12
"""
13
Return a sorted copy of an array.
14
15
Parameters:
16
- a: array_like, input array
17
- axis: int, axis along which to sort
18
- kind: str, sorting algorithm (ignored, uses optimal GPU algorithm)
19
- order: str or list of str, field order for structured arrays
20
21
Returns:
22
cupy.ndarray: sorted array
23
"""
24
25
def argsort(a, axis=-1, kind=None, order=None):
26
"""
27
Returns the indices that would sort an array.
28
29
Parameters:
30
- a: array_like, input array
31
- axis: int, axis along which to sort
32
- kind: str, sorting algorithm (ignored, uses optimal GPU algorithm)
33
- order: str or list of str, field order for structured arrays
34
35
Returns:
36
cupy.ndarray: indices that sort the array
37
"""
38
39
def lexsort(keys, axis=-1):
40
"""
41
Perform an indirect stable sort using a sequence of keys.
42
43
Parameters:
44
- keys: tuple of array_like, sequence of arrays to use as sort keys
45
- axis: int, axis along which to sort
46
47
Returns:
48
cupy.ndarray: indices for lexicographic sort
49
"""
50
51
def msort(a):
52
"""
53
Return a copy of an array sorted along the first axis.
54
55
Parameters:
56
- a: array_like, input array
57
58
Returns:
59
cupy.ndarray: sorted array along first axis
60
"""
61
62
def sort_complex(a):
63
"""
64
Sort a complex array using the real part first, then the imaginary part.
65
66
Parameters:
67
- a: array_like, input array
68
69
Returns:
70
cupy.ndarray: sorted complex array
71
"""
72
```
73
74
### Partial Sorting
75
76
Functions for partial sorting and partitioning.
77
78
```python { .api }
79
def partition(a, kth, axis=-1, kind=None, order=None):
80
"""
81
Return a partitioned copy of an array.
82
83
Parameters:
84
- a: array_like, input array
85
- kth: int or sequence of ints, element index to partition around
86
- axis: int, axis along which to partition
87
- kind: str, selection algorithm (ignored)
88
- order: str or list of str, field order for structured arrays
89
90
Returns:
91
cupy.ndarray: partitioned array
92
"""
93
94
def argpartition(a, kth, axis=-1, kind=None, order=None):
95
"""
96
Perform an indirect partition along the given axis.
97
98
Parameters:
99
- a: array_like, input array
100
- kth: int or sequence of ints, element index to partition around
101
- axis: int, axis along which to partition
102
- kind: str, selection algorithm (ignored)
103
- order: str or list of str, field order for structured arrays
104
105
Returns:
106
cupy.ndarray: indices that partition the array
107
"""
108
```
109
110
### Counting Functions
111
112
Functions for counting elements and occurrences.
113
114
```python { .api }
115
def count_nonzero(a, axis=None, keepdims=False):
116
"""
117
Counts the number of non-zero values in the array.
118
119
Parameters:
120
- a: array_like, input array
121
- axis: None, int, or tuple, axis along which to count
122
- keepdims: bool, whether to keep dimensions in result
123
124
Returns:
125
int or cupy.ndarray: count of non-zero values
126
"""
127
```
128
129
## Usage Examples
130
131
### Basic Sorting
132
133
```python
134
import cupy as cp
135
136
# Create unsorted array
137
arr = cp.array([3, 1, 4, 1, 5, 9, 2, 6])
138
139
# Sort array
140
sorted_arr = cp.sort(arr)
141
print(sorted_arr) # [1 1 2 3 4 5 6 9]
142
143
# Get sorting indices
144
sort_indices = cp.argsort(arr)
145
print(sort_indices) # [1 3 6 0 2 4 7 5]
146
147
# Verify: original array indexed by sort_indices equals sorted array
148
print(arr[sort_indices]) # [1 1 2 3 4 5 6 9]
149
```
150
151
### Multi-dimensional Sorting
152
153
```python
154
import cupy as cp
155
156
# 2D array
157
arr_2d = cp.array([[3, 1, 4], [1, 5, 9], [2, 6, 5]])
158
159
# Sort along different axes
160
sorted_axis0 = cp.sort(arr_2d, axis=0) # Sort columns
161
print(sorted_axis0)
162
# [[1 1 4]
163
# [2 5 5]
164
# [3 6 9]]
165
166
sorted_axis1 = cp.sort(arr_2d, axis=1) # Sort rows
167
print(sorted_axis1)
168
# [[1 3 4]
169
# [1 5 9]
170
# [2 5 6]]
171
```
172
173
### Lexicographic Sorting
174
175
```python
176
import cupy as cp
177
178
# Multiple sort keys
179
surnames = cp.array([3, 1, 2, 1, 3]) # Primary key
180
firstnames = cp.array([1, 2, 1, 1, 2]) # Secondary key
181
182
# Sort by surname first, then by firstname
183
indices = cp.lexsort((firstnames, surnames))
184
print(indices) # [3 1 2 0 4]
185
186
# Result is sorted first by surnames, then by firstnames
187
print(surnames[indices]) # [1 1 2 3 3]
188
print(firstnames[indices]) # [1 2 1 1 2]
189
```
190
191
### Partitioning
192
193
```python
194
import cupy as cp
195
196
# Array to partition
197
arr = cp.array([7, 1, 9, 3, 5, 2, 8, 4, 6])
198
199
# Partition around the 4th smallest element (index 4 when sorted)
200
partitioned = cp.partition(arr, 4)
201
print(partitioned) # Elements <= 5th smallest on left, rest on right
202
203
# Get partition indices
204
partition_indices = cp.argpartition(arr, 4)
205
print(partition_indices)
206
207
# The 4th index contains the 5th smallest element
208
kth_element = partitioned[4]
209
print(f"5th smallest element: {kth_element}")
210
```
211
212
### Counting Operations
213
214
```python
215
import cupy as cp
216
217
# Array with some zeros
218
arr = cp.array([[0, 1, 2], [3, 0, 4], [5, 6, 0]])
219
220
# Count non-zero elements
221
total_nonzero = cp.count_nonzero(arr)
222
print(total_nonzero) # 6
223
224
# Count along axes
225
nonzero_per_row = cp.count_nonzero(arr, axis=1)
226
print(nonzero_per_row) # [2 2 2]
227
228
nonzero_per_col = cp.count_nonzero(arr, axis=0)
229
print(nonzero_per_col) # [2 2 2]
230
```
231
232
### Complex Number Sorting
233
234
```python
235
import cupy as cp
236
237
# Complex array
238
complex_arr = cp.array([1+2j, 3+1j, 2+3j, 1+1j])
239
240
# Sort complex numbers (by real part first, then imaginary)
241
sorted_complex = cp.sort_complex(complex_arr)
242
print(sorted_complex) # [1+1j 1+2j 2+3j 3+1j]
243
```
244
245
### Advanced Sorting Applications
246
247
```python
248
import cupy as cp
249
250
# Student scores in multiple subjects
251
math_scores = cp.array([85, 92, 78, 96, 88])
252
english_scores = cp.array([88, 85, 92, 89, 91])
253
student_ids = cp.array([101, 102, 103, 104, 105])
254
255
# Sort students by total score (descending)
256
total_scores = math_scores + english_scores
257
sort_indices = cp.argsort(-total_scores) # Negative for descending
258
259
print("Ranking by total score:")
260
for i, idx in enumerate(sort_indices):
261
print(f"{i+1}. Student {student_ids[idx]}: "
262
f"Math={math_scores[idx]}, English={english_scores[idx]}, "
263
f"Total={total_scores[idx]}")
264
```