Find the duplicates in a structured array along a given key Parameters ---------- a : array-like Input array key : {string, None}, optional Name of the fields along which to check the duplicates. If None, the search is performed by records ignoremask
(a, key=None, ignoremask=True, return_index=False)
| 1415 | |
| 1416 | @array_function_dispatch(_find_duplicates_dispatcher) |
| 1417 | def find_duplicates(a, key=None, ignoremask=True, return_index=False): |
| 1418 | """ |
| 1419 | Find the duplicates in a structured array along a given key |
| 1420 | |
| 1421 | Parameters |
| 1422 | ---------- |
| 1423 | a : array-like |
| 1424 | Input array |
| 1425 | key : {string, None}, optional |
| 1426 | Name of the fields along which to check the duplicates. |
| 1427 | If None, the search is performed by records |
| 1428 | ignoremask : {True, False}, optional |
| 1429 | Whether masked data should be discarded or considered as duplicates. |
| 1430 | return_index : {False, True}, optional |
| 1431 | Whether to return the indices of the duplicated values. |
| 1432 | |
| 1433 | Examples |
| 1434 | -------- |
| 1435 | >>> import numpy as np |
| 1436 | >>> from numpy.lib import recfunctions as rfn |
| 1437 | >>> ndtype = [('a', int)] |
| 1438 | >>> a = np.ma.array([1, 1, 1, 2, 2, 3, 3], |
| 1439 | ... mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype) |
| 1440 | >>> rfn.find_duplicates(a, ignoremask=True, return_index=True) |
| 1441 | (masked_array(data=[(1,), (1,), (2,), (2,)], |
| 1442 | mask=[(False,), (False,), (False,), (False,)], |
| 1443 | fill_value=(999999,), |
| 1444 | dtype=[('a', '<i8')]), array([0, 1, 3, 4])) |
| 1445 | """ |
| 1446 | a = np.asanyarray(a).ravel() |
| 1447 | # Get a dictionary of fields |
| 1448 | fields = get_fieldstructure(a.dtype) |
| 1449 | # Get the sorting data (by selecting the corresponding field) |
| 1450 | base = a |
| 1451 | if key: |
| 1452 | for f in fields[key]: |
| 1453 | base = base[f] |
| 1454 | base = base[key] |
| 1455 | # Get the sorting indices and the sorted data |
| 1456 | sortidx = base.argsort() |
| 1457 | sortedbase = base[sortidx] |
| 1458 | sorteddata = sortedbase.filled() |
| 1459 | # Compare the sorting data |
| 1460 | flag = (sorteddata[:-1] == sorteddata[1:]) |
| 1461 | # If masked data must be ignored, set the flag to false where needed |
| 1462 | if ignoremask: |
| 1463 | sortedmask = sortedbase.recordmask |
| 1464 | flag[sortedmask[1:]] = False |
| 1465 | flag = np.concatenate(([False], flag)) |
| 1466 | # We need to take the point on the left as well (else we're missing it) |
| 1467 | flag[:-1] = flag[:-1] + flag[1:] |
| 1468 | duplicates = a[sortidx][flag] |
| 1469 | if return_index: |
| 1470 | return (duplicates, sortidx[flag]) |
| 1471 | else: |
| 1472 | return duplicates |
| 1473 | |
| 1474 |
searching dependent graphs…