numpy 2.4.0__cp313-cp313t-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (915) hide show
  1. numpy/__config__.py +170 -0
  2. numpy/__config__.pyi +108 -0
  3. numpy/__init__.cython-30.pxd +1242 -0
  4. numpy/__init__.pxd +1155 -0
  5. numpy/__init__.py +942 -0
  6. numpy/__init__.pyi +6202 -0
  7. numpy/_array_api_info.py +346 -0
  8. numpy/_array_api_info.pyi +206 -0
  9. numpy/_configtool.py +39 -0
  10. numpy/_configtool.pyi +1 -0
  11. numpy/_core/__init__.py +201 -0
  12. numpy/_core/__init__.pyi +666 -0
  13. numpy/_core/_add_newdocs.py +7151 -0
  14. numpy/_core/_add_newdocs.pyi +2 -0
  15. numpy/_core/_add_newdocs_scalars.py +381 -0
  16. numpy/_core/_add_newdocs_scalars.pyi +16 -0
  17. numpy/_core/_asarray.py +130 -0
  18. numpy/_core/_asarray.pyi +43 -0
  19. numpy/_core/_dtype.py +366 -0
  20. numpy/_core/_dtype.pyi +56 -0
  21. numpy/_core/_dtype_ctypes.py +120 -0
  22. numpy/_core/_dtype_ctypes.pyi +83 -0
  23. numpy/_core/_exceptions.py +162 -0
  24. numpy/_core/_exceptions.pyi +54 -0
  25. numpy/_core/_internal.py +968 -0
  26. numpy/_core/_internal.pyi +61 -0
  27. numpy/_core/_methods.py +252 -0
  28. numpy/_core/_methods.pyi +22 -0
  29. numpy/_core/_multiarray_tests.cpython-313t-aarch64-linux-musl.so +0 -0
  30. numpy/_core/_multiarray_umath.cpython-313t-aarch64-linux-musl.so +0 -0
  31. numpy/_core/_operand_flag_tests.cpython-313t-aarch64-linux-musl.so +0 -0
  32. numpy/_core/_rational_tests.cpython-313t-aarch64-linux-musl.so +0 -0
  33. numpy/_core/_simd.cpython-313t-aarch64-linux-musl.so +0 -0
  34. numpy/_core/_simd.pyi +35 -0
  35. numpy/_core/_string_helpers.py +100 -0
  36. numpy/_core/_string_helpers.pyi +12 -0
  37. numpy/_core/_struct_ufunc_tests.cpython-313t-aarch64-linux-musl.so +0 -0
  38. numpy/_core/_type_aliases.py +131 -0
  39. numpy/_core/_type_aliases.pyi +86 -0
  40. numpy/_core/_ufunc_config.py +515 -0
  41. numpy/_core/_ufunc_config.pyi +69 -0
  42. numpy/_core/_umath_tests.cpython-313t-aarch64-linux-musl.so +0 -0
  43. numpy/_core/_umath_tests.pyi +47 -0
  44. numpy/_core/arrayprint.py +1779 -0
  45. numpy/_core/arrayprint.pyi +158 -0
  46. numpy/_core/cversions.py +13 -0
  47. numpy/_core/defchararray.py +1414 -0
  48. numpy/_core/defchararray.pyi +1150 -0
  49. numpy/_core/einsumfunc.py +1650 -0
  50. numpy/_core/einsumfunc.pyi +184 -0
  51. numpy/_core/fromnumeric.py +4233 -0
  52. numpy/_core/fromnumeric.pyi +1735 -0
  53. numpy/_core/function_base.py +547 -0
  54. numpy/_core/function_base.pyi +276 -0
  55. numpy/_core/getlimits.py +462 -0
  56. numpy/_core/getlimits.pyi +124 -0
  57. numpy/_core/include/numpy/__multiarray_api.c +376 -0
  58. numpy/_core/include/numpy/__multiarray_api.h +1628 -0
  59. numpy/_core/include/numpy/__ufunc_api.c +55 -0
  60. numpy/_core/include/numpy/__ufunc_api.h +349 -0
  61. numpy/_core/include/numpy/_neighborhood_iterator_imp.h +90 -0
  62. numpy/_core/include/numpy/_numpyconfig.h +33 -0
  63. numpy/_core/include/numpy/_public_dtype_api_table.h +86 -0
  64. numpy/_core/include/numpy/arrayobject.h +7 -0
  65. numpy/_core/include/numpy/arrayscalars.h +198 -0
  66. numpy/_core/include/numpy/dtype_api.h +547 -0
  67. numpy/_core/include/numpy/halffloat.h +70 -0
  68. numpy/_core/include/numpy/ndarrayobject.h +304 -0
  69. numpy/_core/include/numpy/ndarraytypes.h +1982 -0
  70. numpy/_core/include/numpy/npy_2_compat.h +249 -0
  71. numpy/_core/include/numpy/npy_2_complexcompat.h +28 -0
  72. numpy/_core/include/numpy/npy_3kcompat.h +374 -0
  73. numpy/_core/include/numpy/npy_common.h +989 -0
  74. numpy/_core/include/numpy/npy_cpu.h +126 -0
  75. numpy/_core/include/numpy/npy_endian.h +79 -0
  76. numpy/_core/include/numpy/npy_math.h +602 -0
  77. numpy/_core/include/numpy/npy_no_deprecated_api.h +20 -0
  78. numpy/_core/include/numpy/npy_os.h +42 -0
  79. numpy/_core/include/numpy/numpyconfig.h +185 -0
  80. numpy/_core/include/numpy/random/LICENSE.txt +21 -0
  81. numpy/_core/include/numpy/random/bitgen.h +20 -0
  82. numpy/_core/include/numpy/random/distributions.h +209 -0
  83. numpy/_core/include/numpy/random/libdivide.h +2079 -0
  84. numpy/_core/include/numpy/ufuncobject.h +343 -0
  85. numpy/_core/include/numpy/utils.h +37 -0
  86. numpy/_core/lib/libnpymath.a +0 -0
  87. numpy/_core/lib/npy-pkg-config/mlib.ini +12 -0
  88. numpy/_core/lib/npy-pkg-config/npymath.ini +20 -0
  89. numpy/_core/lib/pkgconfig/numpy.pc +7 -0
  90. numpy/_core/memmap.py +363 -0
  91. numpy/_core/memmap.pyi +3 -0
  92. numpy/_core/multiarray.py +1740 -0
  93. numpy/_core/multiarray.pyi +1316 -0
  94. numpy/_core/numeric.py +2758 -0
  95. numpy/_core/numeric.pyi +1276 -0
  96. numpy/_core/numerictypes.py +633 -0
  97. numpy/_core/numerictypes.pyi +196 -0
  98. numpy/_core/overrides.py +188 -0
  99. numpy/_core/overrides.pyi +47 -0
  100. numpy/_core/printoptions.py +32 -0
  101. numpy/_core/printoptions.pyi +28 -0
  102. numpy/_core/records.py +1088 -0
  103. numpy/_core/records.pyi +340 -0
  104. numpy/_core/shape_base.py +996 -0
  105. numpy/_core/shape_base.pyi +182 -0
  106. numpy/_core/strings.py +1813 -0
  107. numpy/_core/strings.pyi +536 -0
  108. numpy/_core/tests/_locales.py +72 -0
  109. numpy/_core/tests/_natype.py +144 -0
  110. numpy/_core/tests/data/astype_copy.pkl +0 -0
  111. numpy/_core/tests/data/generate_umath_validation_data.cpp +170 -0
  112. numpy/_core/tests/data/recarray_from_file.fits +0 -0
  113. numpy/_core/tests/data/umath-validation-set-README.txt +15 -0
  114. numpy/_core/tests/data/umath-validation-set-arccos.csv +1429 -0
  115. numpy/_core/tests/data/umath-validation-set-arccosh.csv +1429 -0
  116. numpy/_core/tests/data/umath-validation-set-arcsin.csv +1429 -0
  117. numpy/_core/tests/data/umath-validation-set-arcsinh.csv +1429 -0
  118. numpy/_core/tests/data/umath-validation-set-arctan.csv +1429 -0
  119. numpy/_core/tests/data/umath-validation-set-arctanh.csv +1429 -0
  120. numpy/_core/tests/data/umath-validation-set-cbrt.csv +1429 -0
  121. numpy/_core/tests/data/umath-validation-set-cos.csv +1375 -0
  122. numpy/_core/tests/data/umath-validation-set-cosh.csv +1429 -0
  123. numpy/_core/tests/data/umath-validation-set-exp.csv +412 -0
  124. numpy/_core/tests/data/umath-validation-set-exp2.csv +1429 -0
  125. numpy/_core/tests/data/umath-validation-set-expm1.csv +1429 -0
  126. numpy/_core/tests/data/umath-validation-set-log.csv +271 -0
  127. numpy/_core/tests/data/umath-validation-set-log10.csv +1629 -0
  128. numpy/_core/tests/data/umath-validation-set-log1p.csv +1429 -0
  129. numpy/_core/tests/data/umath-validation-set-log2.csv +1629 -0
  130. numpy/_core/tests/data/umath-validation-set-sin.csv +1370 -0
  131. numpy/_core/tests/data/umath-validation-set-sinh.csv +1429 -0
  132. numpy/_core/tests/data/umath-validation-set-tan.csv +1429 -0
  133. numpy/_core/tests/data/umath-validation-set-tanh.csv +1429 -0
  134. numpy/_core/tests/examples/cython/checks.pyx +373 -0
  135. numpy/_core/tests/examples/cython/meson.build +43 -0
  136. numpy/_core/tests/examples/cython/setup.py +39 -0
  137. numpy/_core/tests/examples/limited_api/limited_api1.c +17 -0
  138. numpy/_core/tests/examples/limited_api/limited_api2.pyx +11 -0
  139. numpy/_core/tests/examples/limited_api/limited_api_latest.c +19 -0
  140. numpy/_core/tests/examples/limited_api/meson.build +59 -0
  141. numpy/_core/tests/examples/limited_api/setup.py +24 -0
  142. numpy/_core/tests/test__exceptions.py +90 -0
  143. numpy/_core/tests/test_abc.py +54 -0
  144. numpy/_core/tests/test_api.py +655 -0
  145. numpy/_core/tests/test_argparse.py +90 -0
  146. numpy/_core/tests/test_array_api_info.py +113 -0
  147. numpy/_core/tests/test_array_coercion.py +928 -0
  148. numpy/_core/tests/test_array_interface.py +222 -0
  149. numpy/_core/tests/test_arraymethod.py +84 -0
  150. numpy/_core/tests/test_arrayobject.py +75 -0
  151. numpy/_core/tests/test_arrayprint.py +1324 -0
  152. numpy/_core/tests/test_casting_floatingpoint_errors.py +154 -0
  153. numpy/_core/tests/test_casting_unittests.py +955 -0
  154. numpy/_core/tests/test_conversion_utils.py +209 -0
  155. numpy/_core/tests/test_cpu_dispatcher.py +48 -0
  156. numpy/_core/tests/test_cpu_features.py +450 -0
  157. numpy/_core/tests/test_custom_dtypes.py +393 -0
  158. numpy/_core/tests/test_cython.py +352 -0
  159. numpy/_core/tests/test_datetime.py +2792 -0
  160. numpy/_core/tests/test_defchararray.py +858 -0
  161. numpy/_core/tests/test_deprecations.py +460 -0
  162. numpy/_core/tests/test_dlpack.py +190 -0
  163. numpy/_core/tests/test_dtype.py +2110 -0
  164. numpy/_core/tests/test_einsum.py +1351 -0
  165. numpy/_core/tests/test_errstate.py +131 -0
  166. numpy/_core/tests/test_extint128.py +217 -0
  167. numpy/_core/tests/test_finfo.py +86 -0
  168. numpy/_core/tests/test_function_base.py +504 -0
  169. numpy/_core/tests/test_getlimits.py +171 -0
  170. numpy/_core/tests/test_half.py +593 -0
  171. numpy/_core/tests/test_hashtable.py +36 -0
  172. numpy/_core/tests/test_indexerrors.py +122 -0
  173. numpy/_core/tests/test_indexing.py +1692 -0
  174. numpy/_core/tests/test_item_selection.py +167 -0
  175. numpy/_core/tests/test_limited_api.py +102 -0
  176. numpy/_core/tests/test_longdouble.py +370 -0
  177. numpy/_core/tests/test_mem_overlap.py +933 -0
  178. numpy/_core/tests/test_mem_policy.py +453 -0
  179. numpy/_core/tests/test_memmap.py +248 -0
  180. numpy/_core/tests/test_multiarray.py +11008 -0
  181. numpy/_core/tests/test_multiprocessing.py +55 -0
  182. numpy/_core/tests/test_multithreading.py +353 -0
  183. numpy/_core/tests/test_nditer.py +3533 -0
  184. numpy/_core/tests/test_nep50_promotions.py +287 -0
  185. numpy/_core/tests/test_numeric.py +4295 -0
  186. numpy/_core/tests/test_numerictypes.py +650 -0
  187. numpy/_core/tests/test_overrides.py +800 -0
  188. numpy/_core/tests/test_print.py +202 -0
  189. numpy/_core/tests/test_protocols.py +46 -0
  190. numpy/_core/tests/test_records.py +544 -0
  191. numpy/_core/tests/test_regression.py +2677 -0
  192. numpy/_core/tests/test_scalar_ctors.py +203 -0
  193. numpy/_core/tests/test_scalar_methods.py +328 -0
  194. numpy/_core/tests/test_scalarbuffer.py +153 -0
  195. numpy/_core/tests/test_scalarinherit.py +105 -0
  196. numpy/_core/tests/test_scalarmath.py +1168 -0
  197. numpy/_core/tests/test_scalarprint.py +403 -0
  198. numpy/_core/tests/test_shape_base.py +904 -0
  199. numpy/_core/tests/test_simd.py +1345 -0
  200. numpy/_core/tests/test_simd_module.py +105 -0
  201. numpy/_core/tests/test_stringdtype.py +1855 -0
  202. numpy/_core/tests/test_strings.py +1515 -0
  203. numpy/_core/tests/test_ufunc.py +3405 -0
  204. numpy/_core/tests/test_umath.py +4962 -0
  205. numpy/_core/tests/test_umath_accuracy.py +132 -0
  206. numpy/_core/tests/test_umath_complex.py +631 -0
  207. numpy/_core/tests/test_unicode.py +369 -0
  208. numpy/_core/umath.py +60 -0
  209. numpy/_core/umath.pyi +232 -0
  210. numpy/_distributor_init.py +15 -0
  211. numpy/_distributor_init.pyi +1 -0
  212. numpy/_expired_attrs_2_0.py +78 -0
  213. numpy/_expired_attrs_2_0.pyi +61 -0
  214. numpy/_globals.py +121 -0
  215. numpy/_globals.pyi +17 -0
  216. numpy/_pyinstaller/__init__.py +0 -0
  217. numpy/_pyinstaller/__init__.pyi +0 -0
  218. numpy/_pyinstaller/hook-numpy.py +36 -0
  219. numpy/_pyinstaller/hook-numpy.pyi +6 -0
  220. numpy/_pyinstaller/tests/__init__.py +16 -0
  221. numpy/_pyinstaller/tests/pyinstaller-smoke.py +32 -0
  222. numpy/_pyinstaller/tests/test_pyinstaller.py +35 -0
  223. numpy/_pytesttester.py +201 -0
  224. numpy/_pytesttester.pyi +18 -0
  225. numpy/_typing/__init__.py +173 -0
  226. numpy/_typing/_add_docstring.py +153 -0
  227. numpy/_typing/_array_like.py +106 -0
  228. numpy/_typing/_char_codes.py +213 -0
  229. numpy/_typing/_dtype_like.py +114 -0
  230. numpy/_typing/_extended_precision.py +15 -0
  231. numpy/_typing/_nbit.py +19 -0
  232. numpy/_typing/_nbit_base.py +94 -0
  233. numpy/_typing/_nbit_base.pyi +39 -0
  234. numpy/_typing/_nested_sequence.py +79 -0
  235. numpy/_typing/_scalars.py +20 -0
  236. numpy/_typing/_shape.py +8 -0
  237. numpy/_typing/_ufunc.py +7 -0
  238. numpy/_typing/_ufunc.pyi +975 -0
  239. numpy/_utils/__init__.py +95 -0
  240. numpy/_utils/__init__.pyi +28 -0
  241. numpy/_utils/_convertions.py +18 -0
  242. numpy/_utils/_convertions.pyi +4 -0
  243. numpy/_utils/_inspect.py +192 -0
  244. numpy/_utils/_inspect.pyi +70 -0
  245. numpy/_utils/_pep440.py +486 -0
  246. numpy/_utils/_pep440.pyi +118 -0
  247. numpy/char/__init__.py +2 -0
  248. numpy/char/__init__.pyi +111 -0
  249. numpy/conftest.py +248 -0
  250. numpy/core/__init__.py +33 -0
  251. numpy/core/__init__.pyi +0 -0
  252. numpy/core/_dtype.py +10 -0
  253. numpy/core/_dtype.pyi +0 -0
  254. numpy/core/_dtype_ctypes.py +10 -0
  255. numpy/core/_dtype_ctypes.pyi +0 -0
  256. numpy/core/_internal.py +27 -0
  257. numpy/core/_multiarray_umath.py +57 -0
  258. numpy/core/_utils.py +21 -0
  259. numpy/core/arrayprint.py +10 -0
  260. numpy/core/defchararray.py +10 -0
  261. numpy/core/einsumfunc.py +10 -0
  262. numpy/core/fromnumeric.py +10 -0
  263. numpy/core/function_base.py +10 -0
  264. numpy/core/getlimits.py +10 -0
  265. numpy/core/multiarray.py +25 -0
  266. numpy/core/numeric.py +12 -0
  267. numpy/core/numerictypes.py +10 -0
  268. numpy/core/overrides.py +10 -0
  269. numpy/core/overrides.pyi +7 -0
  270. numpy/core/records.py +10 -0
  271. numpy/core/shape_base.py +10 -0
  272. numpy/core/umath.py +10 -0
  273. numpy/ctypeslib/__init__.py +13 -0
  274. numpy/ctypeslib/__init__.pyi +15 -0
  275. numpy/ctypeslib/_ctypeslib.py +603 -0
  276. numpy/ctypeslib/_ctypeslib.pyi +236 -0
  277. numpy/doc/ufuncs.py +138 -0
  278. numpy/dtypes.py +41 -0
  279. numpy/dtypes.pyi +630 -0
  280. numpy/exceptions.py +246 -0
  281. numpy/exceptions.pyi +27 -0
  282. numpy/f2py/__init__.py +86 -0
  283. numpy/f2py/__init__.pyi +5 -0
  284. numpy/f2py/__main__.py +5 -0
  285. numpy/f2py/__version__.py +1 -0
  286. numpy/f2py/__version__.pyi +1 -0
  287. numpy/f2py/_backends/__init__.py +9 -0
  288. numpy/f2py/_backends/__init__.pyi +5 -0
  289. numpy/f2py/_backends/_backend.py +44 -0
  290. numpy/f2py/_backends/_backend.pyi +46 -0
  291. numpy/f2py/_backends/_distutils.py +76 -0
  292. numpy/f2py/_backends/_distutils.pyi +13 -0
  293. numpy/f2py/_backends/_meson.py +244 -0
  294. numpy/f2py/_backends/_meson.pyi +62 -0
  295. numpy/f2py/_backends/meson.build.template +58 -0
  296. numpy/f2py/_isocbind.py +62 -0
  297. numpy/f2py/_isocbind.pyi +13 -0
  298. numpy/f2py/_src_pyf.py +247 -0
  299. numpy/f2py/_src_pyf.pyi +28 -0
  300. numpy/f2py/auxfuncs.py +1004 -0
  301. numpy/f2py/auxfuncs.pyi +262 -0
  302. numpy/f2py/capi_maps.py +811 -0
  303. numpy/f2py/capi_maps.pyi +33 -0
  304. numpy/f2py/cb_rules.py +665 -0
  305. numpy/f2py/cb_rules.pyi +17 -0
  306. numpy/f2py/cfuncs.py +1563 -0
  307. numpy/f2py/cfuncs.pyi +31 -0
  308. numpy/f2py/common_rules.py +143 -0
  309. numpy/f2py/common_rules.pyi +9 -0
  310. numpy/f2py/crackfortran.py +3725 -0
  311. numpy/f2py/crackfortran.pyi +266 -0
  312. numpy/f2py/diagnose.py +149 -0
  313. numpy/f2py/diagnose.pyi +1 -0
  314. numpy/f2py/f2py2e.py +788 -0
  315. numpy/f2py/f2py2e.pyi +74 -0
  316. numpy/f2py/f90mod_rules.py +269 -0
  317. numpy/f2py/f90mod_rules.pyi +16 -0
  318. numpy/f2py/func2subr.py +329 -0
  319. numpy/f2py/func2subr.pyi +7 -0
  320. numpy/f2py/rules.py +1629 -0
  321. numpy/f2py/rules.pyi +41 -0
  322. numpy/f2py/setup.cfg +3 -0
  323. numpy/f2py/src/fortranobject.c +1436 -0
  324. numpy/f2py/src/fortranobject.h +173 -0
  325. numpy/f2py/symbolic.py +1518 -0
  326. numpy/f2py/symbolic.pyi +219 -0
  327. numpy/f2py/tests/__init__.py +16 -0
  328. numpy/f2py/tests/src/abstract_interface/foo.f90 +34 -0
  329. numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90 +6 -0
  330. numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c +235 -0
  331. numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap +1 -0
  332. numpy/f2py/tests/src/assumed_shape/foo_free.f90 +34 -0
  333. numpy/f2py/tests/src/assumed_shape/foo_mod.f90 +41 -0
  334. numpy/f2py/tests/src/assumed_shape/foo_use.f90 +19 -0
  335. numpy/f2py/tests/src/assumed_shape/precision.f90 +4 -0
  336. numpy/f2py/tests/src/block_docstring/foo.f +6 -0
  337. numpy/f2py/tests/src/callback/foo.f +62 -0
  338. numpy/f2py/tests/src/callback/gh17797.f90 +7 -0
  339. numpy/f2py/tests/src/callback/gh18335.f90 +17 -0
  340. numpy/f2py/tests/src/callback/gh25211.f +10 -0
  341. numpy/f2py/tests/src/callback/gh25211.pyf +18 -0
  342. numpy/f2py/tests/src/callback/gh26681.f90 +18 -0
  343. numpy/f2py/tests/src/cli/gh_22819.pyf +6 -0
  344. numpy/f2py/tests/src/cli/hi77.f +3 -0
  345. numpy/f2py/tests/src/cli/hiworld.f90 +3 -0
  346. numpy/f2py/tests/src/common/block.f +11 -0
  347. numpy/f2py/tests/src/common/gh19161.f90 +10 -0
  348. numpy/f2py/tests/src/crackfortran/accesstype.f90 +13 -0
  349. numpy/f2py/tests/src/crackfortran/common_with_division.f +17 -0
  350. numpy/f2py/tests/src/crackfortran/data_common.f +8 -0
  351. numpy/f2py/tests/src/crackfortran/data_multiplier.f +5 -0
  352. numpy/f2py/tests/src/crackfortran/data_stmts.f90 +20 -0
  353. numpy/f2py/tests/src/crackfortran/data_with_comments.f +8 -0
  354. numpy/f2py/tests/src/crackfortran/foo_deps.f90 +6 -0
  355. numpy/f2py/tests/src/crackfortran/gh15035.f +16 -0
  356. numpy/f2py/tests/src/crackfortran/gh17859.f +12 -0
  357. numpy/f2py/tests/src/crackfortran/gh22648.pyf +7 -0
  358. numpy/f2py/tests/src/crackfortran/gh23533.f +5 -0
  359. numpy/f2py/tests/src/crackfortran/gh23598.f90 +4 -0
  360. numpy/f2py/tests/src/crackfortran/gh23598Warn.f90 +11 -0
  361. numpy/f2py/tests/src/crackfortran/gh23879.f90 +20 -0
  362. numpy/f2py/tests/src/crackfortran/gh27697.f90 +12 -0
  363. numpy/f2py/tests/src/crackfortran/gh2848.f90 +13 -0
  364. numpy/f2py/tests/src/crackfortran/operators.f90 +49 -0
  365. numpy/f2py/tests/src/crackfortran/privatemod.f90 +11 -0
  366. numpy/f2py/tests/src/crackfortran/publicmod.f90 +10 -0
  367. numpy/f2py/tests/src/crackfortran/pubprivmod.f90 +10 -0
  368. numpy/f2py/tests/src/crackfortran/unicode_comment.f90 +4 -0
  369. numpy/f2py/tests/src/f2cmap/.f2py_f2cmap +1 -0
  370. numpy/f2py/tests/src/f2cmap/isoFortranEnvMap.f90 +9 -0
  371. numpy/f2py/tests/src/isocintrin/isoCtests.f90 +34 -0
  372. numpy/f2py/tests/src/kind/foo.f90 +20 -0
  373. numpy/f2py/tests/src/mixed/foo.f +5 -0
  374. numpy/f2py/tests/src/mixed/foo_fixed.f90 +8 -0
  375. numpy/f2py/tests/src/mixed/foo_free.f90 +8 -0
  376. numpy/f2py/tests/src/modules/gh25337/data.f90 +8 -0
  377. numpy/f2py/tests/src/modules/gh25337/use_data.f90 +6 -0
  378. numpy/f2py/tests/src/modules/gh26920/two_mods_with_no_public_entities.f90 +21 -0
  379. numpy/f2py/tests/src/modules/gh26920/two_mods_with_one_public_routine.f90 +21 -0
  380. numpy/f2py/tests/src/modules/module_data_docstring.f90 +12 -0
  381. numpy/f2py/tests/src/modules/use_modules.f90 +20 -0
  382. numpy/f2py/tests/src/negative_bounds/issue_20853.f90 +7 -0
  383. numpy/f2py/tests/src/parameter/constant_array.f90 +45 -0
  384. numpy/f2py/tests/src/parameter/constant_both.f90 +57 -0
  385. numpy/f2py/tests/src/parameter/constant_compound.f90 +15 -0
  386. numpy/f2py/tests/src/parameter/constant_integer.f90 +22 -0
  387. numpy/f2py/tests/src/parameter/constant_non_compound.f90 +23 -0
  388. numpy/f2py/tests/src/parameter/constant_real.f90 +23 -0
  389. numpy/f2py/tests/src/quoted_character/foo.f +14 -0
  390. numpy/f2py/tests/src/regression/AB.inc +1 -0
  391. numpy/f2py/tests/src/regression/assignOnlyModule.f90 +25 -0
  392. numpy/f2py/tests/src/regression/datonly.f90 +17 -0
  393. numpy/f2py/tests/src/regression/f77comments.f +26 -0
  394. numpy/f2py/tests/src/regression/f77fixedform.f95 +5 -0
  395. numpy/f2py/tests/src/regression/f90continuation.f90 +9 -0
  396. numpy/f2py/tests/src/regression/incfile.f90 +5 -0
  397. numpy/f2py/tests/src/regression/inout.f90 +9 -0
  398. numpy/f2py/tests/src/regression/lower_f2py_fortran.f90 +5 -0
  399. numpy/f2py/tests/src/regression/mod_derived_types.f90 +23 -0
  400. numpy/f2py/tests/src/return_character/foo77.f +45 -0
  401. numpy/f2py/tests/src/return_character/foo90.f90 +48 -0
  402. numpy/f2py/tests/src/return_complex/foo77.f +45 -0
  403. numpy/f2py/tests/src/return_complex/foo90.f90 +48 -0
  404. numpy/f2py/tests/src/return_integer/foo77.f +56 -0
  405. numpy/f2py/tests/src/return_integer/foo90.f90 +59 -0
  406. numpy/f2py/tests/src/return_logical/foo77.f +56 -0
  407. numpy/f2py/tests/src/return_logical/foo90.f90 +59 -0
  408. numpy/f2py/tests/src/return_real/foo77.f +45 -0
  409. numpy/f2py/tests/src/return_real/foo90.f90 +48 -0
  410. numpy/f2py/tests/src/routines/funcfortranname.f +5 -0
  411. numpy/f2py/tests/src/routines/funcfortranname.pyf +11 -0
  412. numpy/f2py/tests/src/routines/subrout.f +4 -0
  413. numpy/f2py/tests/src/routines/subrout.pyf +10 -0
  414. numpy/f2py/tests/src/size/foo.f90 +44 -0
  415. numpy/f2py/tests/src/string/char.f90 +29 -0
  416. numpy/f2py/tests/src/string/fixed_string.f90 +34 -0
  417. numpy/f2py/tests/src/string/gh24008.f +8 -0
  418. numpy/f2py/tests/src/string/gh24662.f90 +7 -0
  419. numpy/f2py/tests/src/string/gh25286.f90 +14 -0
  420. numpy/f2py/tests/src/string/gh25286.pyf +12 -0
  421. numpy/f2py/tests/src/string/gh25286_bc.pyf +12 -0
  422. numpy/f2py/tests/src/string/scalar_string.f90 +9 -0
  423. numpy/f2py/tests/src/string/string.f +12 -0
  424. numpy/f2py/tests/src/value_attrspec/gh21665.f90 +9 -0
  425. numpy/f2py/tests/test_abstract_interface.py +26 -0
  426. numpy/f2py/tests/test_array_from_pyobj.py +678 -0
  427. numpy/f2py/tests/test_assumed_shape.py +50 -0
  428. numpy/f2py/tests/test_block_docstring.py +20 -0
  429. numpy/f2py/tests/test_callback.py +263 -0
  430. numpy/f2py/tests/test_character.py +641 -0
  431. numpy/f2py/tests/test_common.py +23 -0
  432. numpy/f2py/tests/test_crackfortran.py +421 -0
  433. numpy/f2py/tests/test_data.py +71 -0
  434. numpy/f2py/tests/test_docs.py +66 -0
  435. numpy/f2py/tests/test_f2cmap.py +17 -0
  436. numpy/f2py/tests/test_f2py2e.py +983 -0
  437. numpy/f2py/tests/test_isoc.py +56 -0
  438. numpy/f2py/tests/test_kind.py +52 -0
  439. numpy/f2py/tests/test_mixed.py +35 -0
  440. numpy/f2py/tests/test_modules.py +83 -0
  441. numpy/f2py/tests/test_parameter.py +129 -0
  442. numpy/f2py/tests/test_pyf_src.py +43 -0
  443. numpy/f2py/tests/test_quoted_character.py +18 -0
  444. numpy/f2py/tests/test_regression.py +187 -0
  445. numpy/f2py/tests/test_return_character.py +48 -0
  446. numpy/f2py/tests/test_return_complex.py +67 -0
  447. numpy/f2py/tests/test_return_integer.py +55 -0
  448. numpy/f2py/tests/test_return_logical.py +65 -0
  449. numpy/f2py/tests/test_return_real.py +109 -0
  450. numpy/f2py/tests/test_routines.py +29 -0
  451. numpy/f2py/tests/test_semicolon_split.py +75 -0
  452. numpy/f2py/tests/test_size.py +45 -0
  453. numpy/f2py/tests/test_string.py +100 -0
  454. numpy/f2py/tests/test_symbolic.py +500 -0
  455. numpy/f2py/tests/test_value_attrspec.py +15 -0
  456. numpy/f2py/tests/util.py +442 -0
  457. numpy/f2py/use_rules.py +99 -0
  458. numpy/f2py/use_rules.pyi +9 -0
  459. numpy/fft/__init__.py +213 -0
  460. numpy/fft/__init__.pyi +38 -0
  461. numpy/fft/_helper.py +235 -0
  462. numpy/fft/_helper.pyi +44 -0
  463. numpy/fft/_pocketfft.py +1693 -0
  464. numpy/fft/_pocketfft.pyi +137 -0
  465. numpy/fft/_pocketfft_umath.cpython-313t-aarch64-linux-musl.so +0 -0
  466. numpy/fft/tests/__init__.py +0 -0
  467. numpy/fft/tests/test_helper.py +167 -0
  468. numpy/fft/tests/test_pocketfft.py +589 -0
  469. numpy/lib/__init__.py +97 -0
  470. numpy/lib/__init__.pyi +52 -0
  471. numpy/lib/_array_utils_impl.py +62 -0
  472. numpy/lib/_array_utils_impl.pyi +10 -0
  473. numpy/lib/_arraypad_impl.py +926 -0
  474. numpy/lib/_arraypad_impl.pyi +88 -0
  475. numpy/lib/_arraysetops_impl.py +1158 -0
  476. numpy/lib/_arraysetops_impl.pyi +462 -0
  477. numpy/lib/_arrayterator_impl.py +224 -0
  478. numpy/lib/_arrayterator_impl.pyi +45 -0
  479. numpy/lib/_datasource.py +700 -0
  480. numpy/lib/_datasource.pyi +30 -0
  481. numpy/lib/_format_impl.py +1036 -0
  482. numpy/lib/_format_impl.pyi +56 -0
  483. numpy/lib/_function_base_impl.py +5758 -0
  484. numpy/lib/_function_base_impl.pyi +2324 -0
  485. numpy/lib/_histograms_impl.py +1085 -0
  486. numpy/lib/_histograms_impl.pyi +40 -0
  487. numpy/lib/_index_tricks_impl.py +1048 -0
  488. numpy/lib/_index_tricks_impl.pyi +267 -0
  489. numpy/lib/_iotools.py +900 -0
  490. numpy/lib/_iotools.pyi +116 -0
  491. numpy/lib/_nanfunctions_impl.py +2001 -0
  492. numpy/lib/_nanfunctions_impl.pyi +48 -0
  493. numpy/lib/_npyio_impl.py +2583 -0
  494. numpy/lib/_npyio_impl.pyi +299 -0
  495. numpy/lib/_polynomial_impl.py +1465 -0
  496. numpy/lib/_polynomial_impl.pyi +338 -0
  497. numpy/lib/_scimath_impl.py +642 -0
  498. numpy/lib/_scimath_impl.pyi +93 -0
  499. numpy/lib/_shape_base_impl.py +1289 -0
  500. numpy/lib/_shape_base_impl.pyi +236 -0
  501. numpy/lib/_stride_tricks_impl.py +582 -0
  502. numpy/lib/_stride_tricks_impl.pyi +73 -0
  503. numpy/lib/_twodim_base_impl.py +1201 -0
  504. numpy/lib/_twodim_base_impl.pyi +408 -0
  505. numpy/lib/_type_check_impl.py +710 -0
  506. numpy/lib/_type_check_impl.pyi +348 -0
  507. numpy/lib/_ufunclike_impl.py +199 -0
  508. numpy/lib/_ufunclike_impl.pyi +60 -0
  509. numpy/lib/_user_array_impl.py +310 -0
  510. numpy/lib/_user_array_impl.pyi +226 -0
  511. numpy/lib/_utils_impl.py +784 -0
  512. numpy/lib/_utils_impl.pyi +22 -0
  513. numpy/lib/_version.py +153 -0
  514. numpy/lib/_version.pyi +17 -0
  515. numpy/lib/array_utils.py +7 -0
  516. numpy/lib/array_utils.pyi +6 -0
  517. numpy/lib/format.py +24 -0
  518. numpy/lib/format.pyi +24 -0
  519. numpy/lib/introspect.py +94 -0
  520. numpy/lib/introspect.pyi +3 -0
  521. numpy/lib/mixins.py +180 -0
  522. numpy/lib/mixins.pyi +78 -0
  523. numpy/lib/npyio.py +1 -0
  524. numpy/lib/npyio.pyi +5 -0
  525. numpy/lib/recfunctions.py +1681 -0
  526. numpy/lib/recfunctions.pyi +444 -0
  527. numpy/lib/scimath.py +13 -0
  528. numpy/lib/scimath.pyi +12 -0
  529. numpy/lib/stride_tricks.py +1 -0
  530. numpy/lib/stride_tricks.pyi +4 -0
  531. numpy/lib/tests/__init__.py +0 -0
  532. numpy/lib/tests/data/py2-np0-objarr.npy +0 -0
  533. numpy/lib/tests/data/py2-objarr.npy +0 -0
  534. numpy/lib/tests/data/py2-objarr.npz +0 -0
  535. numpy/lib/tests/data/py3-objarr.npy +0 -0
  536. numpy/lib/tests/data/py3-objarr.npz +0 -0
  537. numpy/lib/tests/data/python3.npy +0 -0
  538. numpy/lib/tests/data/win64python2.npy +0 -0
  539. numpy/lib/tests/test__datasource.py +328 -0
  540. numpy/lib/tests/test__iotools.py +358 -0
  541. numpy/lib/tests/test__version.py +64 -0
  542. numpy/lib/tests/test_array_utils.py +32 -0
  543. numpy/lib/tests/test_arraypad.py +1427 -0
  544. numpy/lib/tests/test_arraysetops.py +1302 -0
  545. numpy/lib/tests/test_arrayterator.py +45 -0
  546. numpy/lib/tests/test_format.py +1054 -0
  547. numpy/lib/tests/test_function_base.py +4705 -0
  548. numpy/lib/tests/test_histograms.py +855 -0
  549. numpy/lib/tests/test_index_tricks.py +693 -0
  550. numpy/lib/tests/test_io.py +2857 -0
  551. numpy/lib/tests/test_loadtxt.py +1099 -0
  552. numpy/lib/tests/test_mixins.py +215 -0
  553. numpy/lib/tests/test_nanfunctions.py +1438 -0
  554. numpy/lib/tests/test_packbits.py +376 -0
  555. numpy/lib/tests/test_polynomial.py +325 -0
  556. numpy/lib/tests/test_recfunctions.py +1042 -0
  557. numpy/lib/tests/test_regression.py +231 -0
  558. numpy/lib/tests/test_shape_base.py +813 -0
  559. numpy/lib/tests/test_stride_tricks.py +655 -0
  560. numpy/lib/tests/test_twodim_base.py +559 -0
  561. numpy/lib/tests/test_type_check.py +473 -0
  562. numpy/lib/tests/test_ufunclike.py +97 -0
  563. numpy/lib/tests/test_utils.py +80 -0
  564. numpy/lib/user_array.py +1 -0
  565. numpy/lib/user_array.pyi +1 -0
  566. numpy/linalg/__init__.py +95 -0
  567. numpy/linalg/__init__.pyi +71 -0
  568. numpy/linalg/_linalg.py +3657 -0
  569. numpy/linalg/_linalg.pyi +548 -0
  570. numpy/linalg/_umath_linalg.cpython-313t-aarch64-linux-musl.so +0 -0
  571. numpy/linalg/_umath_linalg.pyi +60 -0
  572. numpy/linalg/lapack_lite.cpython-313t-aarch64-linux-musl.so +0 -0
  573. numpy/linalg/lapack_lite.pyi +143 -0
  574. numpy/linalg/tests/__init__.py +0 -0
  575. numpy/linalg/tests/test_deprecations.py +21 -0
  576. numpy/linalg/tests/test_linalg.py +2442 -0
  577. numpy/linalg/tests/test_regression.py +182 -0
  578. numpy/ma/API_CHANGES.txt +135 -0
  579. numpy/ma/LICENSE +24 -0
  580. numpy/ma/README.rst +236 -0
  581. numpy/ma/__init__.py +53 -0
  582. numpy/ma/__init__.pyi +458 -0
  583. numpy/ma/core.py +8929 -0
  584. numpy/ma/core.pyi +3720 -0
  585. numpy/ma/extras.py +2266 -0
  586. numpy/ma/extras.pyi +297 -0
  587. numpy/ma/mrecords.py +762 -0
  588. numpy/ma/mrecords.pyi +96 -0
  589. numpy/ma/tests/__init__.py +0 -0
  590. numpy/ma/tests/test_arrayobject.py +40 -0
  591. numpy/ma/tests/test_core.py +6008 -0
  592. numpy/ma/tests/test_deprecations.py +65 -0
  593. numpy/ma/tests/test_extras.py +1945 -0
  594. numpy/ma/tests/test_mrecords.py +495 -0
  595. numpy/ma/tests/test_old_ma.py +939 -0
  596. numpy/ma/tests/test_regression.py +83 -0
  597. numpy/ma/tests/test_subclassing.py +469 -0
  598. numpy/ma/testutils.py +294 -0
  599. numpy/ma/testutils.pyi +69 -0
  600. numpy/matlib.py +380 -0
  601. numpy/matlib.pyi +580 -0
  602. numpy/matrixlib/__init__.py +12 -0
  603. numpy/matrixlib/__init__.pyi +3 -0
  604. numpy/matrixlib/defmatrix.py +1119 -0
  605. numpy/matrixlib/defmatrix.pyi +218 -0
  606. numpy/matrixlib/tests/__init__.py +0 -0
  607. numpy/matrixlib/tests/test_defmatrix.py +455 -0
  608. numpy/matrixlib/tests/test_interaction.py +360 -0
  609. numpy/matrixlib/tests/test_masked_matrix.py +240 -0
  610. numpy/matrixlib/tests/test_matrix_linalg.py +110 -0
  611. numpy/matrixlib/tests/test_multiarray.py +17 -0
  612. numpy/matrixlib/tests/test_numeric.py +18 -0
  613. numpy/matrixlib/tests/test_regression.py +31 -0
  614. numpy/polynomial/__init__.py +187 -0
  615. numpy/polynomial/__init__.pyi +31 -0
  616. numpy/polynomial/_polybase.py +1191 -0
  617. numpy/polynomial/_polybase.pyi +262 -0
  618. numpy/polynomial/_polytypes.pyi +501 -0
  619. numpy/polynomial/chebyshev.py +2001 -0
  620. numpy/polynomial/chebyshev.pyi +180 -0
  621. numpy/polynomial/hermite.py +1738 -0
  622. numpy/polynomial/hermite.pyi +106 -0
  623. numpy/polynomial/hermite_e.py +1640 -0
  624. numpy/polynomial/hermite_e.pyi +106 -0
  625. numpy/polynomial/laguerre.py +1673 -0
  626. numpy/polynomial/laguerre.pyi +100 -0
  627. numpy/polynomial/legendre.py +1603 -0
  628. numpy/polynomial/legendre.pyi +100 -0
  629. numpy/polynomial/polynomial.py +1625 -0
  630. numpy/polynomial/polynomial.pyi +109 -0
  631. numpy/polynomial/polyutils.py +759 -0
  632. numpy/polynomial/polyutils.pyi +307 -0
  633. numpy/polynomial/tests/__init__.py +0 -0
  634. numpy/polynomial/tests/test_chebyshev.py +618 -0
  635. numpy/polynomial/tests/test_classes.py +613 -0
  636. numpy/polynomial/tests/test_hermite.py +553 -0
  637. numpy/polynomial/tests/test_hermite_e.py +554 -0
  638. numpy/polynomial/tests/test_laguerre.py +535 -0
  639. numpy/polynomial/tests/test_legendre.py +566 -0
  640. numpy/polynomial/tests/test_polynomial.py +691 -0
  641. numpy/polynomial/tests/test_polyutils.py +123 -0
  642. numpy/polynomial/tests/test_printing.py +557 -0
  643. numpy/polynomial/tests/test_symbol.py +217 -0
  644. numpy/py.typed +0 -0
  645. numpy/random/LICENSE.md +71 -0
  646. numpy/random/__init__.pxd +14 -0
  647. numpy/random/__init__.py +213 -0
  648. numpy/random/__init__.pyi +124 -0
  649. numpy/random/_bounded_integers.cpython-313t-aarch64-linux-musl.so +0 -0
  650. numpy/random/_bounded_integers.pxd +29 -0
  651. numpy/random/_bounded_integers.pyi +1 -0
  652. numpy/random/_common.cpython-313t-aarch64-linux-musl.so +0 -0
  653. numpy/random/_common.pxd +107 -0
  654. numpy/random/_common.pyi +16 -0
  655. numpy/random/_examples/cffi/extending.py +44 -0
  656. numpy/random/_examples/cffi/parse.py +53 -0
  657. numpy/random/_examples/cython/extending.pyx +77 -0
  658. numpy/random/_examples/cython/extending_distributions.pyx +117 -0
  659. numpy/random/_examples/cython/meson.build +53 -0
  660. numpy/random/_examples/numba/extending.py +86 -0
  661. numpy/random/_examples/numba/extending_distributions.py +67 -0
  662. numpy/random/_generator.cpython-313t-aarch64-linux-musl.so +0 -0
  663. numpy/random/_generator.pyi +862 -0
  664. numpy/random/_mt19937.cpython-313t-aarch64-linux-musl.so +0 -0
  665. numpy/random/_mt19937.pyi +27 -0
  666. numpy/random/_pcg64.cpython-313t-aarch64-linux-musl.so +0 -0
  667. numpy/random/_pcg64.pyi +41 -0
  668. numpy/random/_philox.cpython-313t-aarch64-linux-musl.so +0 -0
  669. numpy/random/_philox.pyi +36 -0
  670. numpy/random/_pickle.py +88 -0
  671. numpy/random/_pickle.pyi +43 -0
  672. numpy/random/_sfc64.cpython-313t-aarch64-linux-musl.so +0 -0
  673. numpy/random/_sfc64.pyi +25 -0
  674. numpy/random/bit_generator.cpython-313t-aarch64-linux-musl.so +0 -0
  675. numpy/random/bit_generator.pxd +35 -0
  676. numpy/random/bit_generator.pyi +123 -0
  677. numpy/random/c_distributions.pxd +119 -0
  678. numpy/random/lib/libnpyrandom.a +0 -0
  679. numpy/random/mtrand.cpython-313t-aarch64-linux-musl.so +0 -0
  680. numpy/random/mtrand.pyi +759 -0
  681. numpy/random/tests/__init__.py +0 -0
  682. numpy/random/tests/data/__init__.py +0 -0
  683. numpy/random/tests/data/generator_pcg64_np121.pkl.gz +0 -0
  684. numpy/random/tests/data/generator_pcg64_np126.pkl.gz +0 -0
  685. numpy/random/tests/data/mt19937-testset-1.csv +1001 -0
  686. numpy/random/tests/data/mt19937-testset-2.csv +1001 -0
  687. numpy/random/tests/data/pcg64-testset-1.csv +1001 -0
  688. numpy/random/tests/data/pcg64-testset-2.csv +1001 -0
  689. numpy/random/tests/data/pcg64dxsm-testset-1.csv +1001 -0
  690. numpy/random/tests/data/pcg64dxsm-testset-2.csv +1001 -0
  691. numpy/random/tests/data/philox-testset-1.csv +1001 -0
  692. numpy/random/tests/data/philox-testset-2.csv +1001 -0
  693. numpy/random/tests/data/sfc64-testset-1.csv +1001 -0
  694. numpy/random/tests/data/sfc64-testset-2.csv +1001 -0
  695. numpy/random/tests/data/sfc64_np126.pkl.gz +0 -0
  696. numpy/random/tests/test_direct.py +595 -0
  697. numpy/random/tests/test_extending.py +131 -0
  698. numpy/random/tests/test_generator_mt19937.py +2825 -0
  699. numpy/random/tests/test_generator_mt19937_regressions.py +221 -0
  700. numpy/random/tests/test_random.py +1724 -0
  701. numpy/random/tests/test_randomstate.py +2099 -0
  702. numpy/random/tests/test_randomstate_regression.py +213 -0
  703. numpy/random/tests/test_regression.py +175 -0
  704. numpy/random/tests/test_seed_sequence.py +79 -0
  705. numpy/random/tests/test_smoke.py +882 -0
  706. numpy/rec/__init__.py +2 -0
  707. numpy/rec/__init__.pyi +23 -0
  708. numpy/strings/__init__.py +2 -0
  709. numpy/strings/__init__.pyi +97 -0
  710. numpy/testing/__init__.py +22 -0
  711. numpy/testing/__init__.pyi +107 -0
  712. numpy/testing/_private/__init__.py +0 -0
  713. numpy/testing/_private/__init__.pyi +0 -0
  714. numpy/testing/_private/extbuild.py +250 -0
  715. numpy/testing/_private/extbuild.pyi +25 -0
  716. numpy/testing/_private/utils.py +2830 -0
  717. numpy/testing/_private/utils.pyi +505 -0
  718. numpy/testing/overrides.py +84 -0
  719. numpy/testing/overrides.pyi +10 -0
  720. numpy/testing/print_coercion_tables.py +207 -0
  721. numpy/testing/print_coercion_tables.pyi +26 -0
  722. numpy/testing/tests/__init__.py +0 -0
  723. numpy/testing/tests/test_utils.py +2123 -0
  724. numpy/tests/__init__.py +0 -0
  725. numpy/tests/test__all__.py +10 -0
  726. numpy/tests/test_configtool.py +51 -0
  727. numpy/tests/test_ctypeslib.py +383 -0
  728. numpy/tests/test_lazyloading.py +42 -0
  729. numpy/tests/test_matlib.py +59 -0
  730. numpy/tests/test_numpy_config.py +47 -0
  731. numpy/tests/test_numpy_version.py +54 -0
  732. numpy/tests/test_public_api.py +804 -0
  733. numpy/tests/test_reloading.py +76 -0
  734. numpy/tests/test_scripts.py +48 -0
  735. numpy/tests/test_warnings.py +79 -0
  736. numpy/typing/__init__.py +233 -0
  737. numpy/typing/__init__.pyi +3 -0
  738. numpy/typing/mypy_plugin.py +200 -0
  739. numpy/typing/tests/__init__.py +0 -0
  740. numpy/typing/tests/data/fail/arithmetic.pyi +126 -0
  741. numpy/typing/tests/data/fail/array_constructors.pyi +34 -0
  742. numpy/typing/tests/data/fail/array_like.pyi +15 -0
  743. numpy/typing/tests/data/fail/array_pad.pyi +6 -0
  744. numpy/typing/tests/data/fail/arrayprint.pyi +15 -0
  745. numpy/typing/tests/data/fail/arrayterator.pyi +14 -0
  746. numpy/typing/tests/data/fail/bitwise_ops.pyi +17 -0
  747. numpy/typing/tests/data/fail/char.pyi +63 -0
  748. numpy/typing/tests/data/fail/chararray.pyi +61 -0
  749. numpy/typing/tests/data/fail/comparisons.pyi +27 -0
  750. numpy/typing/tests/data/fail/constants.pyi +3 -0
  751. numpy/typing/tests/data/fail/datasource.pyi +16 -0
  752. numpy/typing/tests/data/fail/dtype.pyi +17 -0
  753. numpy/typing/tests/data/fail/einsumfunc.pyi +12 -0
  754. numpy/typing/tests/data/fail/flatiter.pyi +38 -0
  755. numpy/typing/tests/data/fail/fromnumeric.pyi +148 -0
  756. numpy/typing/tests/data/fail/histograms.pyi +12 -0
  757. numpy/typing/tests/data/fail/index_tricks.pyi +14 -0
  758. numpy/typing/tests/data/fail/lib_function_base.pyi +60 -0
  759. numpy/typing/tests/data/fail/lib_polynomial.pyi +29 -0
  760. numpy/typing/tests/data/fail/lib_utils.pyi +3 -0
  761. numpy/typing/tests/data/fail/lib_version.pyi +6 -0
  762. numpy/typing/tests/data/fail/linalg.pyi +52 -0
  763. numpy/typing/tests/data/fail/ma.pyi +155 -0
  764. numpy/typing/tests/data/fail/memmap.pyi +5 -0
  765. numpy/typing/tests/data/fail/modules.pyi +17 -0
  766. numpy/typing/tests/data/fail/multiarray.pyi +52 -0
  767. numpy/typing/tests/data/fail/ndarray.pyi +11 -0
  768. numpy/typing/tests/data/fail/ndarray_misc.pyi +49 -0
  769. numpy/typing/tests/data/fail/nditer.pyi +8 -0
  770. numpy/typing/tests/data/fail/nested_sequence.pyi +17 -0
  771. numpy/typing/tests/data/fail/npyio.pyi +24 -0
  772. numpy/typing/tests/data/fail/numerictypes.pyi +5 -0
  773. numpy/typing/tests/data/fail/random.pyi +62 -0
  774. numpy/typing/tests/data/fail/rec.pyi +17 -0
  775. numpy/typing/tests/data/fail/scalars.pyi +86 -0
  776. numpy/typing/tests/data/fail/shape.pyi +7 -0
  777. numpy/typing/tests/data/fail/shape_base.pyi +8 -0
  778. numpy/typing/tests/data/fail/stride_tricks.pyi +9 -0
  779. numpy/typing/tests/data/fail/strings.pyi +52 -0
  780. numpy/typing/tests/data/fail/testing.pyi +28 -0
  781. numpy/typing/tests/data/fail/twodim_base.pyi +39 -0
  782. numpy/typing/tests/data/fail/type_check.pyi +12 -0
  783. numpy/typing/tests/data/fail/ufunc_config.pyi +21 -0
  784. numpy/typing/tests/data/fail/ufunclike.pyi +21 -0
  785. numpy/typing/tests/data/fail/ufuncs.pyi +17 -0
  786. numpy/typing/tests/data/fail/warnings_and_errors.pyi +5 -0
  787. numpy/typing/tests/data/misc/extended_precision.pyi +9 -0
  788. numpy/typing/tests/data/mypy.ini +8 -0
  789. numpy/typing/tests/data/pass/arithmetic.py +614 -0
  790. numpy/typing/tests/data/pass/array_constructors.py +138 -0
  791. numpy/typing/tests/data/pass/array_like.py +43 -0
  792. numpy/typing/tests/data/pass/arrayprint.py +37 -0
  793. numpy/typing/tests/data/pass/arrayterator.py +28 -0
  794. numpy/typing/tests/data/pass/bitwise_ops.py +131 -0
  795. numpy/typing/tests/data/pass/comparisons.py +316 -0
  796. numpy/typing/tests/data/pass/dtype.py +57 -0
  797. numpy/typing/tests/data/pass/einsumfunc.py +36 -0
  798. numpy/typing/tests/data/pass/flatiter.py +26 -0
  799. numpy/typing/tests/data/pass/fromnumeric.py +272 -0
  800. numpy/typing/tests/data/pass/index_tricks.py +62 -0
  801. numpy/typing/tests/data/pass/lib_user_array.py +22 -0
  802. numpy/typing/tests/data/pass/lib_utils.py +19 -0
  803. numpy/typing/tests/data/pass/lib_version.py +18 -0
  804. numpy/typing/tests/data/pass/literal.py +52 -0
  805. numpy/typing/tests/data/pass/ma.py +199 -0
  806. numpy/typing/tests/data/pass/mod.py +149 -0
  807. numpy/typing/tests/data/pass/modules.py +45 -0
  808. numpy/typing/tests/data/pass/multiarray.py +77 -0
  809. numpy/typing/tests/data/pass/ndarray_conversion.py +81 -0
  810. numpy/typing/tests/data/pass/ndarray_misc.py +199 -0
  811. numpy/typing/tests/data/pass/ndarray_shape_manipulation.py +47 -0
  812. numpy/typing/tests/data/pass/nditer.py +4 -0
  813. numpy/typing/tests/data/pass/numeric.py +90 -0
  814. numpy/typing/tests/data/pass/numerictypes.py +17 -0
  815. numpy/typing/tests/data/pass/random.py +1498 -0
  816. numpy/typing/tests/data/pass/recfunctions.py +164 -0
  817. numpy/typing/tests/data/pass/scalars.py +249 -0
  818. numpy/typing/tests/data/pass/shape.py +19 -0
  819. numpy/typing/tests/data/pass/simple.py +170 -0
  820. numpy/typing/tests/data/pass/ufunc_config.py +64 -0
  821. numpy/typing/tests/data/pass/ufunclike.py +52 -0
  822. numpy/typing/tests/data/pass/ufuncs.py +16 -0
  823. numpy/typing/tests/data/pass/warnings_and_errors.py +6 -0
  824. numpy/typing/tests/data/reveal/arithmetic.pyi +719 -0
  825. numpy/typing/tests/data/reveal/array_api_info.pyi +70 -0
  826. numpy/typing/tests/data/reveal/array_constructors.pyi +277 -0
  827. numpy/typing/tests/data/reveal/arraypad.pyi +27 -0
  828. numpy/typing/tests/data/reveal/arrayprint.pyi +25 -0
  829. numpy/typing/tests/data/reveal/arraysetops.pyi +74 -0
  830. numpy/typing/tests/data/reveal/arrayterator.pyi +27 -0
  831. numpy/typing/tests/data/reveal/bitwise_ops.pyi +166 -0
  832. numpy/typing/tests/data/reveal/char.pyi +225 -0
  833. numpy/typing/tests/data/reveal/chararray.pyi +138 -0
  834. numpy/typing/tests/data/reveal/comparisons.pyi +264 -0
  835. numpy/typing/tests/data/reveal/constants.pyi +14 -0
  836. numpy/typing/tests/data/reveal/ctypeslib.pyi +81 -0
  837. numpy/typing/tests/data/reveal/datasource.pyi +23 -0
  838. numpy/typing/tests/data/reveal/dtype.pyi +132 -0
  839. numpy/typing/tests/data/reveal/einsumfunc.pyi +39 -0
  840. numpy/typing/tests/data/reveal/emath.pyi +54 -0
  841. numpy/typing/tests/data/reveal/fft.pyi +37 -0
  842. numpy/typing/tests/data/reveal/flatiter.pyi +86 -0
  843. numpy/typing/tests/data/reveal/fromnumeric.pyi +347 -0
  844. numpy/typing/tests/data/reveal/getlimits.pyi +53 -0
  845. numpy/typing/tests/data/reveal/histograms.pyi +25 -0
  846. numpy/typing/tests/data/reveal/index_tricks.pyi +70 -0
  847. numpy/typing/tests/data/reveal/lib_function_base.pyi +409 -0
  848. numpy/typing/tests/data/reveal/lib_polynomial.pyi +147 -0
  849. numpy/typing/tests/data/reveal/lib_utils.pyi +17 -0
  850. numpy/typing/tests/data/reveal/lib_version.pyi +20 -0
  851. numpy/typing/tests/data/reveal/linalg.pyi +154 -0
  852. numpy/typing/tests/data/reveal/ma.pyi +1098 -0
  853. numpy/typing/tests/data/reveal/matrix.pyi +73 -0
  854. numpy/typing/tests/data/reveal/memmap.pyi +19 -0
  855. numpy/typing/tests/data/reveal/mod.pyi +178 -0
  856. numpy/typing/tests/data/reveal/modules.pyi +51 -0
  857. numpy/typing/tests/data/reveal/multiarray.pyi +197 -0
  858. numpy/typing/tests/data/reveal/nbit_base_example.pyi +20 -0
  859. numpy/typing/tests/data/reveal/ndarray_assignability.pyi +82 -0
  860. numpy/typing/tests/data/reveal/ndarray_conversion.pyi +83 -0
  861. numpy/typing/tests/data/reveal/ndarray_misc.pyi +246 -0
  862. numpy/typing/tests/data/reveal/ndarray_shape_manipulation.pyi +47 -0
  863. numpy/typing/tests/data/reveal/nditer.pyi +49 -0
  864. numpy/typing/tests/data/reveal/nested_sequence.pyi +25 -0
  865. numpy/typing/tests/data/reveal/npyio.pyi +83 -0
  866. numpy/typing/tests/data/reveal/numeric.pyi +170 -0
  867. numpy/typing/tests/data/reveal/numerictypes.pyi +16 -0
  868. numpy/typing/tests/data/reveal/polynomial_polybase.pyi +217 -0
  869. numpy/typing/tests/data/reveal/polynomial_polyutils.pyi +218 -0
  870. numpy/typing/tests/data/reveal/polynomial_series.pyi +138 -0
  871. numpy/typing/tests/data/reveal/random.pyi +1546 -0
  872. numpy/typing/tests/data/reveal/rec.pyi +171 -0
  873. numpy/typing/tests/data/reveal/scalars.pyi +191 -0
  874. numpy/typing/tests/data/reveal/shape.pyi +13 -0
  875. numpy/typing/tests/data/reveal/shape_base.pyi +52 -0
  876. numpy/typing/tests/data/reveal/stride_tricks.pyi +27 -0
  877. numpy/typing/tests/data/reveal/strings.pyi +196 -0
  878. numpy/typing/tests/data/reveal/testing.pyi +198 -0
  879. numpy/typing/tests/data/reveal/twodim_base.pyi +225 -0
  880. numpy/typing/tests/data/reveal/type_check.pyi +67 -0
  881. numpy/typing/tests/data/reveal/ufunc_config.pyi +29 -0
  882. numpy/typing/tests/data/reveal/ufunclike.pyi +31 -0
  883. numpy/typing/tests/data/reveal/ufuncs.pyi +142 -0
  884. numpy/typing/tests/data/reveal/warnings_and_errors.pyi +11 -0
  885. numpy/typing/tests/test_isfile.py +38 -0
  886. numpy/typing/tests/test_runtime.py +110 -0
  887. numpy/typing/tests/test_typing.py +205 -0
  888. numpy/version.py +11 -0
  889. numpy/version.pyi +9 -0
  890. numpy-2.4.0.dist-info/METADATA +139 -0
  891. numpy-2.4.0.dist-info/RECORD +915 -0
  892. numpy-2.4.0.dist-info/WHEEL +5 -0
  893. numpy-2.4.0.dist-info/entry_points.txt +13 -0
  894. numpy-2.4.0.dist-info/licenses/LICENSE.txt +935 -0
  895. numpy-2.4.0.dist-info/licenses/numpy/_core/include/numpy/libdivide/LICENSE.txt +21 -0
  896. numpy-2.4.0.dist-info/licenses/numpy/_core/src/common/pythoncapi-compat/COPYING +14 -0
  897. numpy-2.4.0.dist-info/licenses/numpy/_core/src/highway/LICENSE +371 -0
  898. numpy-2.4.0.dist-info/licenses/numpy/_core/src/multiarray/dragon4_LICENSE.txt +27 -0
  899. numpy-2.4.0.dist-info/licenses/numpy/_core/src/npysort/x86-simd-sort/LICENSE.md +28 -0
  900. numpy-2.4.0.dist-info/licenses/numpy/_core/src/umath/svml/LICENSE +30 -0
  901. numpy-2.4.0.dist-info/licenses/numpy/fft/pocketfft/LICENSE.md +25 -0
  902. numpy-2.4.0.dist-info/licenses/numpy/linalg/lapack_lite/LICENSE.txt +48 -0
  903. numpy-2.4.0.dist-info/licenses/numpy/ma/LICENSE +24 -0
  904. numpy-2.4.0.dist-info/licenses/numpy/random/LICENSE.md +71 -0
  905. numpy-2.4.0.dist-info/licenses/numpy/random/src/distributions/LICENSE.md +61 -0
  906. numpy-2.4.0.dist-info/licenses/numpy/random/src/mt19937/LICENSE.md +61 -0
  907. numpy-2.4.0.dist-info/licenses/numpy/random/src/pcg64/LICENSE.md +22 -0
  908. numpy-2.4.0.dist-info/licenses/numpy/random/src/philox/LICENSE.md +31 -0
  909. numpy-2.4.0.dist-info/licenses/numpy/random/src/sfc64/LICENSE.md +27 -0
  910. numpy-2.4.0.dist-info/licenses/numpy/random/src/splitmix64/LICENSE.md +9 -0
  911. numpy.libs/libgcc_s-2d945d6c-767fb991.so.1 +0 -0
  912. numpy.libs/libgcc_s-2d945d6c.so.1 +0 -0
  913. numpy.libs/libgfortran-67378ab2-e7e7cfab.so.5.0.0 +0 -0
  914. numpy.libs/libscipy_openblas64_-1fc386ee.so +0 -0
  915. numpy.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
@@ -0,0 +1,1681 @@
1
+ """
2
+ Collection of utilities to manipulate structured arrays.
3
+
4
+ Most of these functions were initially implemented by John Hunter for
5
+ matplotlib. They have been rewritten and extended for convenience.
6
+
7
+ """
8
+ import itertools
9
+
10
+ import numpy as np
11
+ import numpy.ma as ma
12
+ import numpy.ma.mrecords as mrec
13
+ from numpy._core.overrides import array_function_dispatch
14
+ from numpy.lib._iotools import _is_string_like
15
+
16
+ __all__ = [
17
+ 'append_fields', 'apply_along_fields', 'assign_fields_by_name',
18
+ 'drop_fields', 'find_duplicates', 'flatten_descr',
19
+ 'get_fieldstructure', 'get_names', 'get_names_flat',
20
+ 'join_by', 'merge_arrays', 'rec_append_fields',
21
+ 'rec_drop_fields', 'rec_join', 'recursive_fill_fields',
22
+ 'rename_fields', 'repack_fields', 'require_fields',
23
+ 'stack_arrays', 'structured_to_unstructured', 'unstructured_to_structured',
24
+ ]
25
+
26
+
27
+ def _recursive_fill_fields_dispatcher(input, output):
28
+ return (input, output)
29
+
30
+
31
+ @array_function_dispatch(_recursive_fill_fields_dispatcher)
32
+ def recursive_fill_fields(input, output):
33
+ """
34
+ Fills fields from output with fields from input,
35
+ with support for nested structures.
36
+
37
+ Parameters
38
+ ----------
39
+ input : ndarray
40
+ Input array.
41
+ output : ndarray
42
+ Output array.
43
+
44
+ Notes
45
+ -----
46
+ * `output` should be at least the same size as `input`
47
+
48
+ Examples
49
+ --------
50
+ >>> import numpy as np
51
+ >>> from numpy.lib import recfunctions as rfn
52
+ >>> a = np.array([(1, 10.), (2, 20.)], dtype=[('A', np.int64), ('B', np.float64)])
53
+ >>> b = np.zeros((3,), dtype=a.dtype)
54
+ >>> rfn.recursive_fill_fields(a, b)
55
+ array([(1, 10.), (2, 20.), (0, 0.)], dtype=[('A', '<i8'), ('B', '<f8')])
56
+
57
+ """
58
+ newdtype = output.dtype
59
+ for field in newdtype.names:
60
+ try:
61
+ current = input[field]
62
+ except ValueError:
63
+ continue
64
+ if current.dtype.names is not None:
65
+ recursive_fill_fields(current, output[field])
66
+ else:
67
+ output[field][:len(current)] = current
68
+ return output
69
+
70
+
71
+ def _get_fieldspec(dtype):
72
+ """
73
+ Produce a list of name/dtype pairs corresponding to the dtype fields
74
+
75
+ Similar to dtype.descr, but the second item of each tuple is a dtype, not a
76
+ string. As a result, this handles subarray dtypes
77
+
78
+ Can be passed to the dtype constructor to reconstruct the dtype, noting that
79
+ this (deliberately) discards field offsets.
80
+
81
+ Examples
82
+ --------
83
+ >>> import numpy as np
84
+ >>> dt = np.dtype([(('a', 'A'), np.int64), ('b', np.double, 3)])
85
+ >>> dt.descr
86
+ [(('a', 'A'), '<i8'), ('b', '<f8', (3,))]
87
+ >>> _get_fieldspec(dt)
88
+ [(('a', 'A'), dtype('int64')), ('b', dtype(('<f8', (3,))))]
89
+
90
+ """
91
+ if dtype.names is None:
92
+ # .descr returns a nameless field, so we should too
93
+ return [('', dtype)]
94
+ else:
95
+ fields = ((name, dtype.fields[name]) for name in dtype.names)
96
+ # keep any titles, if present
97
+ return [
98
+ (name if len(f) == 2 else (f[2], name), f[0])
99
+ for name, f in fields
100
+ ]
101
+
102
+
103
+ def get_names(adtype):
104
+ """
105
+ Returns the field names of the input datatype as a tuple. Input datatype
106
+ must have fields otherwise error is raised.
107
+
108
+ Parameters
109
+ ----------
110
+ adtype : dtype
111
+ Input datatype
112
+
113
+ Examples
114
+ --------
115
+ >>> import numpy as np
116
+ >>> from numpy.lib import recfunctions as rfn
117
+ >>> rfn.get_names(np.empty((1,), dtype=[('A', int)]).dtype)
118
+ ('A',)
119
+ >>> rfn.get_names(np.empty((1,), dtype=[('A',int), ('B', float)]).dtype)
120
+ ('A', 'B')
121
+ >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])])
122
+ >>> rfn.get_names(adtype)
123
+ ('a', ('b', ('ba', 'bb')))
124
+ """
125
+ listnames = []
126
+ names = adtype.names
127
+ for name in names:
128
+ current = adtype[name]
129
+ if current.names is not None:
130
+ listnames.append((name, tuple(get_names(current))))
131
+ else:
132
+ listnames.append(name)
133
+ return tuple(listnames)
134
+
135
+
136
+ def get_names_flat(adtype):
137
+ """
138
+ Returns the field names of the input datatype as a tuple. Input datatype
139
+ must have fields otherwise error is raised.
140
+ Nested structure are flattened beforehand.
141
+
142
+ Parameters
143
+ ----------
144
+ adtype : dtype
145
+ Input datatype
146
+
147
+ Examples
148
+ --------
149
+ >>> import numpy as np
150
+ >>> from numpy.lib import recfunctions as rfn
151
+ >>> rfn.get_names_flat(np.empty((1,), dtype=[('A', int)]).dtype) is None
152
+ False
153
+ >>> rfn.get_names_flat(np.empty((1,), dtype=[('A',int), ('B', str)]).dtype)
154
+ ('A', 'B')
155
+ >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])])
156
+ >>> rfn.get_names_flat(adtype)
157
+ ('a', 'b', 'ba', 'bb')
158
+ """
159
+ listnames = []
160
+ names = adtype.names
161
+ for name in names:
162
+ listnames.append(name)
163
+ current = adtype[name]
164
+ if current.names is not None:
165
+ listnames.extend(get_names_flat(current))
166
+ return tuple(listnames)
167
+
168
+
169
+ def flatten_descr(ndtype):
170
+ """
171
+ Flatten a structured data-type description.
172
+
173
+ Examples
174
+ --------
175
+ >>> import numpy as np
176
+ >>> from numpy.lib import recfunctions as rfn
177
+ >>> ndtype = np.dtype([('a', '<i4'), ('b', [('ba', '<f8'), ('bb', '<i4')])])
178
+ >>> rfn.flatten_descr(ndtype)
179
+ (('a', dtype('int32')), ('ba', dtype('float64')), ('bb', dtype('int32')))
180
+
181
+ """
182
+ names = ndtype.names
183
+ if names is None:
184
+ return (('', ndtype),)
185
+ else:
186
+ descr = []
187
+ for field in names:
188
+ (typ, _) = ndtype.fields[field]
189
+ if typ.names is not None:
190
+ descr.extend(flatten_descr(typ))
191
+ else:
192
+ descr.append((field, typ))
193
+ return tuple(descr)
194
+
195
+
196
+ def _zip_dtype(seqarrays, flatten=False):
197
+ newdtype = []
198
+ if flatten:
199
+ for a in seqarrays:
200
+ newdtype.extend(flatten_descr(a.dtype))
201
+ else:
202
+ for a in seqarrays:
203
+ current = a.dtype
204
+ if current.names is not None and len(current.names) == 1:
205
+ # special case - dtypes of 1 field are flattened
206
+ newdtype.extend(_get_fieldspec(current))
207
+ else:
208
+ newdtype.append(('', current))
209
+ return np.dtype(newdtype)
210
+
211
+
212
+ def _zip_descr(seqarrays, flatten=False):
213
+ """
214
+ Combine the dtype description of a series of arrays.
215
+
216
+ Parameters
217
+ ----------
218
+ seqarrays : sequence of arrays
219
+ Sequence of arrays
220
+ flatten : {boolean}, optional
221
+ Whether to collapse nested descriptions.
222
+ """
223
+ return _zip_dtype(seqarrays, flatten=flatten).descr
224
+
225
+
226
+ def get_fieldstructure(adtype, lastname=None, parents=None,):
227
+ """
228
+ Returns a dictionary with fields indexing lists of their parent fields.
229
+
230
+ This function is used to simplify access to fields nested in other fields.
231
+
232
+ Parameters
233
+ ----------
234
+ adtype : np.dtype
235
+ Input datatype
236
+ lastname : optional
237
+ Last processed field name (used internally during recursion).
238
+ parents : dictionary
239
+ Dictionary of parent fields (used internally during recursion).
240
+
241
+ Examples
242
+ --------
243
+ >>> import numpy as np
244
+ >>> from numpy.lib import recfunctions as rfn
245
+ >>> ndtype = np.dtype([('A', int),
246
+ ... ('B', [('BA', int),
247
+ ... ('BB', [('BBA', int), ('BBB', int)])])])
248
+ >>> rfn.get_fieldstructure(ndtype)
249
+ ... # XXX: possible regression, order of BBA and BBB is swapped
250
+ {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'], 'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']}
251
+
252
+ """
253
+ if parents is None:
254
+ parents = {}
255
+ names = adtype.names
256
+ for name in names:
257
+ current = adtype[name]
258
+ if current.names is not None:
259
+ if lastname:
260
+ parents[name] = [lastname, ]
261
+ else:
262
+ parents[name] = []
263
+ parents.update(get_fieldstructure(current, name, parents))
264
+ else:
265
+ lastparent = list(parents.get(lastname, []) or [])
266
+ if lastparent:
267
+ lastparent.append(lastname)
268
+ elif lastname:
269
+ lastparent = [lastname, ]
270
+ parents[name] = lastparent or []
271
+ return parents
272
+
273
+
274
+ def _izip_fields_flat(iterable):
275
+ """
276
+ Returns an iterator of concatenated fields from a sequence of arrays,
277
+ collapsing any nested structure.
278
+
279
+ """
280
+ for element in iterable:
281
+ if isinstance(element, np.void):
282
+ yield from _izip_fields_flat(tuple(element))
283
+ else:
284
+ yield element
285
+
286
+
287
+ def _izip_fields(iterable):
288
+ """
289
+ Returns an iterator of concatenated fields from a sequence of arrays.
290
+
291
+ """
292
+ for element in iterable:
293
+ if (hasattr(element, '__iter__') and
294
+ not isinstance(element, str)):
295
+ yield from _izip_fields(element)
296
+ elif isinstance(element, np.void) and len(tuple(element)) == 1:
297
+ # this statement is the same from the previous expression
298
+ yield from _izip_fields(element)
299
+ else:
300
+ yield element
301
+
302
+
303
+ def _izip_records(seqarrays, fill_value=None, flatten=True):
304
+ """
305
+ Returns an iterator of concatenated items from a sequence of arrays.
306
+
307
+ Parameters
308
+ ----------
309
+ seqarrays : sequence of arrays
310
+ Sequence of arrays.
311
+ fill_value : {None, integer}
312
+ Value used to pad shorter iterables.
313
+ flatten : {True, False},
314
+ Whether to
315
+ """
316
+
317
+ # Should we flatten the items, or just use a nested approach
318
+ if flatten:
319
+ zipfunc = _izip_fields_flat
320
+ else:
321
+ zipfunc = _izip_fields
322
+
323
+ for tup in itertools.zip_longest(*seqarrays, fillvalue=fill_value):
324
+ yield tuple(zipfunc(tup))
325
+
326
+
327
+ def _fix_output(output, usemask=True, asrecarray=False):
328
+ """
329
+ Private function: return a recarray, a ndarray, a MaskedArray
330
+ or a MaskedRecords depending on the input parameters
331
+ """
332
+ if not isinstance(output, ma.MaskedArray):
333
+ usemask = False
334
+ if usemask:
335
+ if asrecarray:
336
+ output = output.view(mrec.MaskedRecords)
337
+ else:
338
+ output = ma.filled(output)
339
+ if asrecarray:
340
+ output = output.view(np.recarray)
341
+ return output
342
+
343
+
344
+ def _fix_defaults(output, defaults=None):
345
+ """
346
+ Update the fill_value and masked data of `output`
347
+ from the default given in a dictionary defaults.
348
+ """
349
+ names = output.dtype.names
350
+ (data, mask, fill_value) = (output.data, output.mask, output.fill_value)
351
+ for (k, v) in (defaults or {}).items():
352
+ if k in names:
353
+ fill_value[k] = v
354
+ data[k][mask[k]] = v
355
+ return output
356
+
357
+
358
+ def _merge_arrays_dispatcher(seqarrays, fill_value=None, flatten=None,
359
+ usemask=None, asrecarray=None):
360
+ return seqarrays
361
+
362
+
363
+ @array_function_dispatch(_merge_arrays_dispatcher)
364
+ def merge_arrays(seqarrays, fill_value=-1, flatten=False,
365
+ usemask=False, asrecarray=False):
366
+ """
367
+ Merge arrays field by field.
368
+
369
+ Parameters
370
+ ----------
371
+ seqarrays : sequence of ndarrays
372
+ Sequence of arrays
373
+ fill_value : {float}, optional
374
+ Filling value used to pad missing data on the shorter arrays.
375
+ flatten : {False, True}, optional
376
+ Whether to collapse nested fields.
377
+ usemask : {False, True}, optional
378
+ Whether to return a masked array or not.
379
+ asrecarray : {False, True}, optional
380
+ Whether to return a recarray (MaskedRecords) or not.
381
+
382
+ Examples
383
+ --------
384
+ >>> import numpy as np
385
+ >>> from numpy.lib import recfunctions as rfn
386
+ >>> rfn.merge_arrays((np.array([1, 2]), np.array([10., 20., 30.])))
387
+ array([( 1, 10.), ( 2, 20.), (-1, 30.)],
388
+ dtype=[('f0', '<i8'), ('f1', '<f8')])
389
+
390
+ >>> rfn.merge_arrays((np.array([1, 2], dtype=np.int64),
391
+ ... np.array([10., 20., 30.])), usemask=False)
392
+ array([(1, 10.0), (2, 20.0), (-1, 30.0)],
393
+ dtype=[('f0', '<i8'), ('f1', '<f8')])
394
+ >>> rfn.merge_arrays((np.array([1, 2]).view([('a', np.int64)]),
395
+ ... np.array([10., 20., 30.])),
396
+ ... usemask=False, asrecarray=True)
397
+ rec.array([( 1, 10.), ( 2, 20.), (-1, 30.)],
398
+ dtype=[('a', '<i8'), ('f1', '<f8')])
399
+
400
+ Notes
401
+ -----
402
+ * Without a mask, the missing value will be filled with something,
403
+ depending on what its corresponding type:
404
+
405
+ * ``-1`` for integers
406
+ * ``-1.0`` for floating point numbers
407
+ * ``'-'`` for characters
408
+ * ``'-1'`` for strings
409
+ * ``True`` for boolean values
410
+ * XXX: I just obtained these values empirically
411
+ """
412
+ # Only one item in the input sequence ?
413
+ if (len(seqarrays) == 1):
414
+ seqarrays = np.asanyarray(seqarrays[0])
415
+ # Do we have a single ndarray as input ?
416
+ if isinstance(seqarrays, (np.ndarray, np.void)):
417
+ seqdtype = seqarrays.dtype
418
+ # Make sure we have named fields
419
+ if seqdtype.names is None:
420
+ seqdtype = np.dtype([('', seqdtype)])
421
+ if not flatten or _zip_dtype((seqarrays,), flatten=True) == seqdtype:
422
+ # Minimal processing needed: just make sure everything's a-ok
423
+ seqarrays = seqarrays.ravel()
424
+ # Find what type of array we must return
425
+ if usemask:
426
+ if asrecarray:
427
+ seqtype = mrec.MaskedRecords
428
+ else:
429
+ seqtype = ma.MaskedArray
430
+ elif asrecarray:
431
+ seqtype = np.recarray
432
+ else:
433
+ seqtype = np.ndarray
434
+ return seqarrays.view(dtype=seqdtype, type=seqtype)
435
+ else:
436
+ seqarrays = (seqarrays,)
437
+ else:
438
+ # Make sure we have arrays in the input sequence
439
+ seqarrays = [np.asanyarray(_m) for _m in seqarrays]
440
+ # Find the sizes of the inputs and their maximum
441
+ sizes = tuple(a.size for a in seqarrays)
442
+ maxlength = max(sizes)
443
+ # Get the dtype of the output (flattening if needed)
444
+ newdtype = _zip_dtype(seqarrays, flatten=flatten)
445
+ # Initialize the sequences for data and mask
446
+ seqdata = []
447
+ seqmask = []
448
+ # If we expect some kind of MaskedArray, make a special loop.
449
+ if usemask:
450
+ for (a, n) in zip(seqarrays, sizes):
451
+ nbmissing = (maxlength - n)
452
+ # Get the data and mask
453
+ data = a.ravel().__array__()
454
+ mask = ma.getmaskarray(a).ravel()
455
+ # Get the filling value (if needed)
456
+ if nbmissing:
457
+ fval = mrec._check_fill_value(fill_value, a.dtype)
458
+ if isinstance(fval, (np.ndarray, np.void)):
459
+ if len(fval.dtype) == 1:
460
+ fval = fval.item()[0]
461
+ fmsk = True
462
+ else:
463
+ fval = np.array(fval, dtype=a.dtype, ndmin=1)
464
+ fmsk = np.ones((1,), dtype=mask.dtype)
465
+ else:
466
+ fval = None
467
+ fmsk = True
468
+ # Store an iterator padding the input to the expected length
469
+ seqdata.append(itertools.chain(data, [fval] * nbmissing))
470
+ seqmask.append(itertools.chain(mask, [fmsk] * nbmissing))
471
+ # Create an iterator for the data
472
+ data = tuple(_izip_records(seqdata, flatten=flatten))
473
+ output = ma.array(np.fromiter(data, dtype=newdtype, count=maxlength),
474
+ mask=list(_izip_records(seqmask, flatten=flatten)))
475
+ if asrecarray:
476
+ output = output.view(mrec.MaskedRecords)
477
+ else:
478
+ # Same as before, without the mask we don't need...
479
+ for (a, n) in zip(seqarrays, sizes):
480
+ nbmissing = (maxlength - n)
481
+ data = a.ravel().__array__()
482
+ if nbmissing:
483
+ fval = mrec._check_fill_value(fill_value, a.dtype)
484
+ if isinstance(fval, (np.ndarray, np.void)):
485
+ if len(fval.dtype) == 1:
486
+ fval = fval.item()[0]
487
+ else:
488
+ fval = np.array(fval, dtype=a.dtype, ndmin=1)
489
+ else:
490
+ fval = None
491
+ seqdata.append(itertools.chain(data, [fval] * nbmissing))
492
+ output = np.fromiter(tuple(_izip_records(seqdata, flatten=flatten)),
493
+ dtype=newdtype, count=maxlength)
494
+ if asrecarray:
495
+ output = output.view(np.recarray)
496
+ # And we're done...
497
+ return output
498
+
499
+
500
+ def _drop_fields_dispatcher(base, drop_names, usemask=None, asrecarray=None):
501
+ return (base,)
502
+
503
+
504
+ @array_function_dispatch(_drop_fields_dispatcher)
505
+ def drop_fields(base, drop_names, usemask=True, asrecarray=False):
506
+ """
507
+ Return a new array with fields in `drop_names` dropped.
508
+
509
+ Nested fields are supported.
510
+
511
+ Parameters
512
+ ----------
513
+ base : array
514
+ Input array
515
+ drop_names : string or sequence
516
+ String or sequence of strings corresponding to the names of the
517
+ fields to drop.
518
+ usemask : {False, True}, optional
519
+ Whether to return a masked array or not.
520
+ asrecarray : string or sequence, optional
521
+ Whether to return a recarray or a mrecarray (`asrecarray=True`) or
522
+ a plain ndarray or masked array with flexible dtype. The default
523
+ is False.
524
+
525
+ Examples
526
+ --------
527
+ >>> import numpy as np
528
+ >>> from numpy.lib import recfunctions as rfn
529
+ >>> a = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
530
+ ... dtype=[('a', np.int64), ('b', [('ba', np.double), ('bb', np.int64)])])
531
+ >>> rfn.drop_fields(a, 'a')
532
+ array([((2., 3),), ((5., 6),)],
533
+ dtype=[('b', [('ba', '<f8'), ('bb', '<i8')])])
534
+ >>> rfn.drop_fields(a, 'ba')
535
+ array([(1, (3,)), (4, (6,))], dtype=[('a', '<i8'), ('b', [('bb', '<i8')])])
536
+ >>> rfn.drop_fields(a, ['ba', 'bb'])
537
+ array([(1,), (4,)], dtype=[('a', '<i8')])
538
+ """
539
+ if _is_string_like(drop_names):
540
+ drop_names = [drop_names]
541
+ else:
542
+ drop_names = set(drop_names)
543
+
544
+ def _drop_descr(ndtype, drop_names):
545
+ names = ndtype.names
546
+ newdtype = []
547
+ for name in names:
548
+ current = ndtype[name]
549
+ if name in drop_names:
550
+ continue
551
+ if current.names is not None:
552
+ descr = _drop_descr(current, drop_names)
553
+ if descr:
554
+ newdtype.append((name, descr))
555
+ else:
556
+ newdtype.append((name, current))
557
+ return newdtype
558
+
559
+ newdtype = _drop_descr(base.dtype, drop_names)
560
+
561
+ output = np.empty(base.shape, dtype=newdtype)
562
+ output = recursive_fill_fields(base, output)
563
+ return _fix_output(output, usemask=usemask, asrecarray=asrecarray)
564
+
565
+
566
+ def _keep_fields(base, keep_names, usemask=True, asrecarray=False):
567
+ """
568
+ Return a new array keeping only the fields in `keep_names`,
569
+ and preserving the order of those fields.
570
+
571
+ Parameters
572
+ ----------
573
+ base : array
574
+ Input array
575
+ keep_names : string or sequence
576
+ String or sequence of strings corresponding to the names of the
577
+ fields to keep. Order of the names will be preserved.
578
+ usemask : {False, True}, optional
579
+ Whether to return a masked array or not.
580
+ asrecarray : string or sequence, optional
581
+ Whether to return a recarray or a mrecarray (`asrecarray=True`) or
582
+ a plain ndarray or masked array with flexible dtype. The default
583
+ is False.
584
+ """
585
+ newdtype = [(n, base.dtype[n]) for n in keep_names]
586
+ output = np.empty(base.shape, dtype=newdtype)
587
+ output = recursive_fill_fields(base, output)
588
+ return _fix_output(output, usemask=usemask, asrecarray=asrecarray)
589
+
590
+
591
+ def _rec_drop_fields_dispatcher(base, drop_names):
592
+ return (base,)
593
+
594
+
595
+ @array_function_dispatch(_rec_drop_fields_dispatcher)
596
+ def rec_drop_fields(base, drop_names):
597
+ """
598
+ Returns a new numpy.recarray with fields in `drop_names` dropped.
599
+ """
600
+ return drop_fields(base, drop_names, usemask=False, asrecarray=True)
601
+
602
+
603
+ def _rename_fields_dispatcher(base, namemapper):
604
+ return (base,)
605
+
606
+
607
+ @array_function_dispatch(_rename_fields_dispatcher)
608
+ def rename_fields(base, namemapper):
609
+ """
610
+ Rename the fields from a flexible-datatype ndarray or recarray.
611
+
612
+ Nested fields are supported.
613
+
614
+ Parameters
615
+ ----------
616
+ base : ndarray
617
+ Input array whose fields must be modified.
618
+ namemapper : dictionary
619
+ Dictionary mapping old field names to their new version.
620
+
621
+ Examples
622
+ --------
623
+ >>> import numpy as np
624
+ >>> from numpy.lib import recfunctions as rfn
625
+ >>> a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))],
626
+ ... dtype=[('a', int),('b', [('ba', float), ('bb', (float, 2))])])
627
+ >>> rfn.rename_fields(a, {'a':'A', 'bb':'BB'})
628
+ array([(1, (2., [ 3., 30.])), (4, (5., [ 6., 60.]))],
629
+ dtype=[('A', '<i8'), ('b', [('ba', '<f8'), ('BB', '<f8', (2,))])])
630
+
631
+ """
632
+ def _recursive_rename_fields(ndtype, namemapper):
633
+ newdtype = []
634
+ for name in ndtype.names:
635
+ newname = namemapper.get(name, name)
636
+ current = ndtype[name]
637
+ if current.names is not None:
638
+ newdtype.append(
639
+ (newname, _recursive_rename_fields(current, namemapper))
640
+ )
641
+ else:
642
+ newdtype.append((newname, current))
643
+ return newdtype
644
+ newdtype = _recursive_rename_fields(base.dtype, namemapper)
645
+ return base.view(newdtype)
646
+
647
+
648
+ def _append_fields_dispatcher(base, names, data, dtypes=None,
649
+ fill_value=None, usemask=None, asrecarray=None):
650
+ yield base
651
+ yield from data
652
+
653
+
654
+ @array_function_dispatch(_append_fields_dispatcher)
655
+ def append_fields(base, names, data, dtypes=None,
656
+ fill_value=-1, usemask=True, asrecarray=False):
657
+ """
658
+ Add new fields to an existing array.
659
+
660
+ The names of the fields are given with the `names` arguments,
661
+ the corresponding values with the `data` arguments.
662
+ If a single field is appended, `names`, `data` and `dtypes` do not have
663
+ to be lists but just values.
664
+
665
+ Parameters
666
+ ----------
667
+ base : array
668
+ Input array to extend.
669
+ names : string, sequence
670
+ String or sequence of strings corresponding to the names
671
+ of the new fields.
672
+ data : array or sequence of arrays
673
+ Array or sequence of arrays storing the fields to add to the base.
674
+ dtypes : sequence of datatypes, optional
675
+ Datatype or sequence of datatypes.
676
+ If None, the datatypes are estimated from the `data`.
677
+ fill_value : {float}, optional
678
+ Filling value used to pad missing data on the shorter arrays.
679
+ usemask : {False, True}, optional
680
+ Whether to return a masked array or not.
681
+ asrecarray : {False, True}, optional
682
+ Whether to return a recarray (MaskedRecords) or not.
683
+
684
+ """
685
+ # Check the names
686
+ if isinstance(names, (tuple, list)):
687
+ if len(names) != len(data):
688
+ msg = "The number of arrays does not match the number of names"
689
+ raise ValueError(msg)
690
+ elif isinstance(names, str):
691
+ names = [names, ]
692
+ data = [data, ]
693
+ #
694
+ if dtypes is None:
695
+ data = [np.array(a, copy=None, subok=True) for a in data]
696
+ data = [a.view([(name, a.dtype)]) for (name, a) in zip(names, data)]
697
+ else:
698
+ if not isinstance(dtypes, (tuple, list)):
699
+ dtypes = [dtypes, ]
700
+ if len(data) != len(dtypes):
701
+ if len(dtypes) == 1:
702
+ dtypes = dtypes * len(data)
703
+ else:
704
+ msg = "The dtypes argument must be None, a dtype, or a list."
705
+ raise ValueError(msg)
706
+ data = [np.array(a, copy=None, subok=True, dtype=d).view([(n, d)])
707
+ for (a, n, d) in zip(data, names, dtypes)]
708
+ #
709
+ base = merge_arrays(base, usemask=usemask, fill_value=fill_value)
710
+ if len(data) > 1:
711
+ data = merge_arrays(data, flatten=True, usemask=usemask,
712
+ fill_value=fill_value)
713
+ else:
714
+ data = data.pop()
715
+ #
716
+ output = ma.masked_all(
717
+ max(len(base), len(data)),
718
+ dtype=_get_fieldspec(base.dtype) + _get_fieldspec(data.dtype))
719
+ output = recursive_fill_fields(base, output)
720
+ output = recursive_fill_fields(data, output)
721
+ #
722
+ return _fix_output(output, usemask=usemask, asrecarray=asrecarray)
723
+
724
+
725
+ def _rec_append_fields_dispatcher(base, names, data, dtypes=None):
726
+ yield base
727
+ yield from data
728
+
729
+
730
+ @array_function_dispatch(_rec_append_fields_dispatcher)
731
+ def rec_append_fields(base, names, data, dtypes=None):
732
+ """
733
+ Add new fields to an existing array.
734
+
735
+ The names of the fields are given with the `names` arguments,
736
+ the corresponding values with the `data` arguments.
737
+ If a single field is appended, `names`, `data` and `dtypes` do not have
738
+ to be lists but just values.
739
+
740
+ Parameters
741
+ ----------
742
+ base : array
743
+ Input array to extend.
744
+ names : string, sequence
745
+ String or sequence of strings corresponding to the names
746
+ of the new fields.
747
+ data : array or sequence of arrays
748
+ Array or sequence of arrays storing the fields to add to the base.
749
+ dtypes : sequence of datatypes, optional
750
+ Datatype or sequence of datatypes.
751
+ If None, the datatypes are estimated from the `data`.
752
+
753
+ See Also
754
+ --------
755
+ append_fields
756
+
757
+ Returns
758
+ -------
759
+ appended_array : np.recarray
760
+ """
761
+ return append_fields(base, names, data=data, dtypes=dtypes,
762
+ asrecarray=True, usemask=False)
763
+
764
+
765
+ def _repack_fields_dispatcher(a, align=None, recurse=None):
766
+ return (a,)
767
+
768
+
769
+ @array_function_dispatch(_repack_fields_dispatcher)
770
+ def repack_fields(a, align=False, recurse=False):
771
+ """
772
+ Re-pack the fields of a structured array or dtype in memory.
773
+
774
+ The memory layout of structured datatypes allows fields at arbitrary
775
+ byte offsets. This means the fields can be separated by padding bytes,
776
+ their offsets can be non-monotonically increasing, and they can overlap.
777
+
778
+ This method removes any overlaps and reorders the fields in memory so they
779
+ have increasing byte offsets, and adds or removes padding bytes depending
780
+ on the `align` option, which behaves like the `align` option to
781
+ `numpy.dtype`.
782
+
783
+ If `align=False`, this method produces a "packed" memory layout in which
784
+ each field starts at the byte the previous field ended, and any padding
785
+ bytes are removed.
786
+
787
+ If `align=True`, this methods produces an "aligned" memory layout in which
788
+ each field's offset is a multiple of its alignment, and the total itemsize
789
+ is a multiple of the largest alignment, by adding padding bytes as needed.
790
+
791
+ Parameters
792
+ ----------
793
+ a : ndarray or dtype
794
+ array or dtype for which to repack the fields.
795
+ align : boolean
796
+ If true, use an "aligned" memory layout, otherwise use a "packed" layout.
797
+ recurse : boolean
798
+ If True, also repack nested structures.
799
+
800
+ Returns
801
+ -------
802
+ repacked : ndarray or dtype
803
+ Copy of `a` with fields repacked, or `a` itself if no repacking was
804
+ needed.
805
+
806
+ Examples
807
+ --------
808
+ >>> import numpy as np
809
+
810
+ >>> from numpy.lib import recfunctions as rfn
811
+ >>> def print_offsets(d):
812
+ ... print("offsets:", [d.fields[name][1] for name in d.names])
813
+ ... print("itemsize:", d.itemsize)
814
+ ...
815
+ >>> dt = np.dtype('u1, <i8, <f8', align=True)
816
+ >>> dt
817
+ dtype({'names': ['f0', 'f1', 'f2'], 'formats': ['u1', '<i8', '<f8'], \
818
+ 'offsets': [0, 8, 16], 'itemsize': 24}, align=True)
819
+ >>> print_offsets(dt)
820
+ offsets: [0, 8, 16]
821
+ itemsize: 24
822
+ >>> packed_dt = rfn.repack_fields(dt)
823
+ >>> packed_dt
824
+ dtype([('f0', 'u1'), ('f1', '<i8'), ('f2', '<f8')])
825
+ >>> print_offsets(packed_dt)
826
+ offsets: [0, 1, 9]
827
+ itemsize: 17
828
+
829
+ """
830
+ if not isinstance(a, np.dtype):
831
+ dt = repack_fields(a.dtype, align=align, recurse=recurse)
832
+ return a.astype(dt, copy=False)
833
+
834
+ if a.names is None:
835
+ return a
836
+
837
+ fieldinfo = []
838
+ for name in a.names:
839
+ tup = a.fields[name]
840
+ if recurse:
841
+ fmt = repack_fields(tup[0], align=align, recurse=True)
842
+ else:
843
+ fmt = tup[0]
844
+
845
+ if len(tup) == 3:
846
+ name = (tup[2], name)
847
+
848
+ fieldinfo.append((name, fmt))
849
+
850
+ dt = np.dtype(fieldinfo, align=align)
851
+ return np.dtype((a.type, dt))
852
+
853
+ def _get_fields_and_offsets(dt, offset=0):
854
+ """
855
+ Returns a flat list of (dtype, count, offset) tuples of all the
856
+ scalar fields in the dtype "dt", including nested fields, in left
857
+ to right order.
858
+ """
859
+
860
+ # counts up elements in subarrays, including nested subarrays, and returns
861
+ # base dtype and count
862
+ def count_elem(dt):
863
+ count = 1
864
+ while dt.shape != ():
865
+ for size in dt.shape:
866
+ count *= size
867
+ dt = dt.base
868
+ return dt, count
869
+
870
+ fields = []
871
+ for name in dt.names:
872
+ field = dt.fields[name]
873
+ f_dt, f_offset = field[0], field[1]
874
+ f_dt, n = count_elem(f_dt)
875
+
876
+ if f_dt.names is None:
877
+ fields.append((np.dtype((f_dt, (n,))), n, f_offset + offset))
878
+ else:
879
+ subfields = _get_fields_and_offsets(f_dt, f_offset + offset)
880
+ size = f_dt.itemsize
881
+
882
+ for i in range(n):
883
+ if i == 0:
884
+ # optimization: avoid list comprehension if no subarray
885
+ fields.extend(subfields)
886
+ else:
887
+ fields.extend([(d, c, o + i * size) for d, c, o in subfields])
888
+ return fields
889
+
890
+ def _common_stride(offsets, counts, itemsize):
891
+ """
892
+ Returns the stride between the fields, or None if the stride is not
893
+ constant. The values in "counts" designate the lengths of
894
+ subarrays. Subarrays are treated as many contiguous fields, with
895
+ always positive stride.
896
+ """
897
+ if len(offsets) <= 1:
898
+ return itemsize
899
+
900
+ negative = offsets[1] < offsets[0] # negative stride
901
+ if negative:
902
+ # reverse, so offsets will be ascending
903
+ it = zip(reversed(offsets), reversed(counts))
904
+ else:
905
+ it = zip(offsets, counts)
906
+
907
+ prev_offset = None
908
+ stride = None
909
+ for offset, count in it:
910
+ if count != 1: # subarray: always c-contiguous
911
+ if negative:
912
+ return None # subarrays can never have a negative stride
913
+ if stride is None:
914
+ stride = itemsize
915
+ if stride != itemsize:
916
+ return None
917
+ end_offset = offset + (count - 1) * itemsize
918
+ else:
919
+ end_offset = offset
920
+
921
+ if prev_offset is not None:
922
+ new_stride = offset - prev_offset
923
+ if stride is None:
924
+ stride = new_stride
925
+ if stride != new_stride:
926
+ return None
927
+
928
+ prev_offset = end_offset
929
+
930
+ if negative:
931
+ return -stride
932
+ return stride
933
+
934
+
935
+ def _structured_to_unstructured_dispatcher(arr, dtype=None, copy=None,
936
+ casting=None):
937
+ return (arr,)
938
+
939
+ @array_function_dispatch(_structured_to_unstructured_dispatcher)
940
+ def structured_to_unstructured(arr, dtype=None, copy=False, casting='unsafe'):
941
+ """
942
+ Converts an n-D structured array into an (n+1)-D unstructured array.
943
+
944
+ The new array will have a new last dimension equal in size to the
945
+ number of field-elements of the input array. If not supplied, the output
946
+ datatype is determined from the numpy type promotion rules applied to all
947
+ the field datatypes.
948
+
949
+ Nested fields, as well as each element of any subarray fields, all count
950
+ as a single field-elements.
951
+
952
+ Parameters
953
+ ----------
954
+ arr : ndarray
955
+ Structured array or dtype to convert. Cannot contain object datatype.
956
+ dtype : dtype, optional
957
+ The dtype of the output unstructured array.
958
+ copy : bool, optional
959
+ If true, always return a copy. If false, a view is returned if
960
+ possible, such as when the `dtype` and strides of the fields are
961
+ suitable and the array subtype is one of `numpy.ndarray`,
962
+ `numpy.recarray` or `numpy.memmap`.
963
+
964
+ .. versionchanged:: 1.25.0
965
+ A view can now be returned if the fields are separated by a
966
+ uniform stride.
967
+
968
+ casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
969
+ See casting argument of `numpy.ndarray.astype`. Controls what kind of
970
+ data casting may occur.
971
+
972
+ Returns
973
+ -------
974
+ unstructured : ndarray
975
+ Unstructured array with one more dimension.
976
+
977
+ Examples
978
+ --------
979
+ >>> import numpy as np
980
+
981
+ >>> from numpy.lib import recfunctions as rfn
982
+ >>> a = np.zeros(4, dtype=[('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)])
983
+ >>> a
984
+ array([(0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.]),
985
+ (0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.])],
986
+ dtype=[('a', '<i4'), ('b', [('f0', '<f4'), ('f1', '<u2')]), ('c', '<f4', (2,))])
987
+ >>> rfn.structured_to_unstructured(a)
988
+ array([[0., 0., 0., 0., 0.],
989
+ [0., 0., 0., 0., 0.],
990
+ [0., 0., 0., 0., 0.],
991
+ [0., 0., 0., 0., 0.]])
992
+
993
+ >>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)],
994
+ ... dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')])
995
+ >>> np.mean(rfn.structured_to_unstructured(b[['x', 'z']]), axis=-1)
996
+ array([ 3. , 5.5, 9. , 11. ])
997
+
998
+ """ # noqa: E501
999
+ if arr.dtype.names is None:
1000
+ raise ValueError('arr must be a structured array')
1001
+
1002
+ fields = _get_fields_and_offsets(arr.dtype)
1003
+ n_fields = len(fields)
1004
+ if n_fields == 0 and dtype is None:
1005
+ raise ValueError("arr has no fields. Unable to guess dtype")
1006
+ elif n_fields == 0:
1007
+ # too many bugs elsewhere for this to work now
1008
+ raise NotImplementedError("arr with no fields is not supported")
1009
+
1010
+ dts, counts, offsets = zip(*fields)
1011
+ names = [f'f{n}' for n in range(n_fields)]
1012
+
1013
+ if dtype is None:
1014
+ out_dtype = np.result_type(*[dt.base for dt in dts])
1015
+ else:
1016
+ out_dtype = np.dtype(dtype)
1017
+
1018
+ # Use a series of views and casts to convert to an unstructured array:
1019
+
1020
+ # first view using flattened fields (doesn't work for object arrays)
1021
+ # Note: dts may include a shape for subarrays
1022
+ flattened_fields = np.dtype({'names': names,
1023
+ 'formats': dts,
1024
+ 'offsets': offsets,
1025
+ 'itemsize': arr.dtype.itemsize})
1026
+ arr = arr.view(flattened_fields)
1027
+
1028
+ # we only allow a few types to be unstructured by manipulating the
1029
+ # strides, because we know it won't work with, for example, np.matrix nor
1030
+ # np.ma.MaskedArray.
1031
+ can_view = type(arr) in (np.ndarray, np.recarray, np.memmap)
1032
+ if (not copy) and can_view and all(dt.base == out_dtype for dt in dts):
1033
+ # all elements have the right dtype already; if they have a common
1034
+ # stride, we can just return a view
1035
+ common_stride = _common_stride(offsets, counts, out_dtype.itemsize)
1036
+ if common_stride is not None:
1037
+ wrap = arr.__array_wrap__
1038
+
1039
+ new_shape = arr.shape + (sum(counts), out_dtype.itemsize)
1040
+ new_strides = arr.strides + (abs(common_stride), 1)
1041
+
1042
+ arr = arr[..., np.newaxis].view(np.uint8) # view as bytes
1043
+ arr = arr[..., min(offsets):] # remove the leading unused data
1044
+ arr = np.lib.stride_tricks.as_strided(arr,
1045
+ new_shape,
1046
+ new_strides,
1047
+ subok=True)
1048
+
1049
+ # cast and drop the last dimension again
1050
+ arr = arr.view(out_dtype)[..., 0]
1051
+
1052
+ if common_stride < 0:
1053
+ arr = arr[..., ::-1] # reverse, if the stride was negative
1054
+ if type(arr) is not type(wrap.__self__):
1055
+ # Some types (e.g. recarray) turn into an ndarray along the
1056
+ # way, so we have to wrap it again in order to match the
1057
+ # behavior with copy=True.
1058
+ arr = wrap(arr)
1059
+ return arr
1060
+
1061
+ # next cast to a packed format with all fields converted to new dtype
1062
+ packed_fields = np.dtype({'names': names,
1063
+ 'formats': [(out_dtype, dt.shape) for dt in dts]})
1064
+ arr = arr.astype(packed_fields, copy=copy, casting=casting)
1065
+
1066
+ # finally is it safe to view the packed fields as the unstructured type
1067
+ return arr.view((out_dtype, (sum(counts),)))
1068
+
1069
+
1070
+ def _unstructured_to_structured_dispatcher(arr, dtype=None, names=None,
1071
+ align=None, copy=None, casting=None):
1072
+ return (arr,)
1073
+
1074
+ @array_function_dispatch(_unstructured_to_structured_dispatcher)
1075
+ def unstructured_to_structured(arr, dtype=None, names=None, align=False,
1076
+ copy=False, casting='unsafe'):
1077
+ """
1078
+ Converts an n-D unstructured array into an (n-1)-D structured array.
1079
+
1080
+ The last dimension of the input array is converted into a structure, with
1081
+ number of field-elements equal to the size of the last dimension of the
1082
+ input array. By default all output fields have the input array's dtype, but
1083
+ an output structured dtype with an equal number of fields-elements can be
1084
+ supplied instead.
1085
+
1086
+ Nested fields, as well as each element of any subarray fields, all count
1087
+ towards the number of field-elements.
1088
+
1089
+ Parameters
1090
+ ----------
1091
+ arr : ndarray
1092
+ Unstructured array or dtype to convert.
1093
+ dtype : dtype, optional
1094
+ The structured dtype of the output array
1095
+ names : list of strings, optional
1096
+ If dtype is not supplied, this specifies the field names for the output
1097
+ dtype, in order. The field dtypes will be the same as the input array.
1098
+ align : boolean, optional
1099
+ Whether to create an aligned memory layout.
1100
+ copy : bool, optional
1101
+ See copy argument to `numpy.ndarray.astype`. If true, always return a
1102
+ copy. If false, and `dtype` requirements are satisfied, a view is
1103
+ returned.
1104
+ casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
1105
+ See casting argument of `numpy.ndarray.astype`. Controls what kind of
1106
+ data casting may occur.
1107
+
1108
+ Returns
1109
+ -------
1110
+ structured : ndarray
1111
+ Structured array with fewer dimensions.
1112
+
1113
+ Examples
1114
+ --------
1115
+ >>> import numpy as np
1116
+
1117
+ >>> from numpy.lib import recfunctions as rfn
1118
+ >>> dt = np.dtype([('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)])
1119
+ >>> a = np.arange(20).reshape((4,5))
1120
+ >>> a
1121
+ array([[ 0, 1, 2, 3, 4],
1122
+ [ 5, 6, 7, 8, 9],
1123
+ [10, 11, 12, 13, 14],
1124
+ [15, 16, 17, 18, 19]])
1125
+ >>> rfn.unstructured_to_structured(a, dt)
1126
+ array([( 0, ( 1., 2), [ 3., 4.]), ( 5, ( 6., 7), [ 8., 9.]),
1127
+ (10, (11., 12), [13., 14.]), (15, (16., 17), [18., 19.])],
1128
+ dtype=[('a', '<i4'), ('b', [('f0', '<f4'), ('f1', '<u2')]), ('c', '<f4', (2,))])
1129
+
1130
+ """ # noqa: E501
1131
+ if arr.shape == ():
1132
+ raise ValueError('arr must have at least one dimension')
1133
+ n_elem = arr.shape[-1]
1134
+ if n_elem == 0:
1135
+ # too many bugs elsewhere for this to work now
1136
+ raise NotImplementedError("last axis with size 0 is not supported")
1137
+
1138
+ if dtype is None:
1139
+ if names is None:
1140
+ names = [f'f{n}' for n in range(n_elem)]
1141
+ out_dtype = np.dtype([(n, arr.dtype) for n in names], align=align)
1142
+ fields = _get_fields_and_offsets(out_dtype)
1143
+ dts, counts, offsets = zip(*fields)
1144
+ else:
1145
+ if names is not None:
1146
+ raise ValueError("don't supply both dtype and names")
1147
+ # if dtype is the args of np.dtype, construct it
1148
+ dtype = np.dtype(dtype)
1149
+ # sanity check of the input dtype
1150
+ fields = _get_fields_and_offsets(dtype)
1151
+ if len(fields) == 0:
1152
+ dts, counts, offsets = [], [], []
1153
+ else:
1154
+ dts, counts, offsets = zip(*fields)
1155
+
1156
+ if n_elem != sum(counts):
1157
+ raise ValueError('The length of the last dimension of arr must '
1158
+ 'be equal to the number of fields in dtype')
1159
+ out_dtype = dtype
1160
+ if align and not out_dtype.isalignedstruct:
1161
+ raise ValueError("align was True but dtype is not aligned")
1162
+
1163
+ names = [f'f{n}' for n in range(len(fields))]
1164
+
1165
+ # Use a series of views and casts to convert to a structured array:
1166
+
1167
+ # first view as a packed structured array of one dtype
1168
+ packed_fields = np.dtype({'names': names,
1169
+ 'formats': [(arr.dtype, dt.shape) for dt in dts]})
1170
+ arr = np.ascontiguousarray(arr).view(packed_fields)
1171
+
1172
+ # next cast to an unpacked but flattened format with varied dtypes
1173
+ flattened_fields = np.dtype({'names': names,
1174
+ 'formats': dts,
1175
+ 'offsets': offsets,
1176
+ 'itemsize': out_dtype.itemsize})
1177
+ arr = arr.astype(flattened_fields, copy=copy, casting=casting)
1178
+
1179
+ # finally view as the final nested dtype and remove the last axis
1180
+ return arr.view(out_dtype)[..., 0]
1181
+
1182
+ def _apply_along_fields_dispatcher(func, arr):
1183
+ return (arr,)
1184
+
1185
+ @array_function_dispatch(_apply_along_fields_dispatcher)
1186
+ def apply_along_fields(func, arr):
1187
+ """
1188
+ Apply function 'func' as a reduction across fields of a structured array.
1189
+
1190
+ This is similar to `numpy.apply_along_axis`, but treats the fields of a
1191
+ structured array as an extra axis. The fields are all first cast to a
1192
+ common type following the type-promotion rules from `numpy.result_type`
1193
+ applied to the field's dtypes.
1194
+
1195
+ Parameters
1196
+ ----------
1197
+ func : function
1198
+ Function to apply on the "field" dimension. This function must
1199
+ support an `axis` argument, like `numpy.mean`, `numpy.sum`, etc.
1200
+ arr : ndarray
1201
+ Structured array for which to apply func.
1202
+
1203
+ Returns
1204
+ -------
1205
+ out : ndarray
1206
+ Result of the reduction operation
1207
+
1208
+ Examples
1209
+ --------
1210
+ >>> import numpy as np
1211
+
1212
+ >>> from numpy.lib import recfunctions as rfn
1213
+ >>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)],
1214
+ ... dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')])
1215
+ >>> rfn.apply_along_fields(np.mean, b)
1216
+ array([ 2.66666667, 5.33333333, 8.66666667, 11. ])
1217
+ >>> rfn.apply_along_fields(np.mean, b[['x', 'z']])
1218
+ array([ 3. , 5.5, 9. , 11. ])
1219
+
1220
+ """
1221
+ if arr.dtype.names is None:
1222
+ raise ValueError('arr must be a structured array')
1223
+
1224
+ uarr = structured_to_unstructured(arr)
1225
+ return func(uarr, axis=-1)
1226
+ # works and avoids axis requirement, but very, very slow:
1227
+ #return np.apply_along_axis(func, -1, uarr)
1228
+
1229
+ def _assign_fields_by_name_dispatcher(dst, src, zero_unassigned=None):
1230
+ return dst, src
1231
+
1232
+ @array_function_dispatch(_assign_fields_by_name_dispatcher)
1233
+ def assign_fields_by_name(dst, src, zero_unassigned=True):
1234
+ """
1235
+ Assigns values from one structured array to another by field name.
1236
+
1237
+ Normally in numpy >= 1.14, assignment of one structured array to another
1238
+ copies fields "by position", meaning that the first field from the src is
1239
+ copied to the first field of the dst, and so on, regardless of field name.
1240
+
1241
+ This function instead copies "by field name", such that fields in the dst
1242
+ are assigned from the identically named field in the src. This applies
1243
+ recursively for nested structures. This is how structure assignment worked
1244
+ in numpy >= 1.6 to <= 1.13.
1245
+
1246
+ Parameters
1247
+ ----------
1248
+ dst : ndarray
1249
+ src : ndarray
1250
+ The source and destination arrays during assignment.
1251
+ zero_unassigned : bool, optional
1252
+ If True, fields in the dst for which there was no matching
1253
+ field in the src are filled with the value 0 (zero). This
1254
+ was the behavior of numpy <= 1.13. If False, those fields
1255
+ are not modified.
1256
+ """
1257
+
1258
+ if dst.dtype.names is None:
1259
+ dst[...] = src
1260
+ return
1261
+
1262
+ for name in dst.dtype.names:
1263
+ if name not in src.dtype.names:
1264
+ if zero_unassigned:
1265
+ dst[name] = 0
1266
+ else:
1267
+ assign_fields_by_name(dst[name], src[name],
1268
+ zero_unassigned)
1269
+
1270
+ def _require_fields_dispatcher(array, required_dtype):
1271
+ return (array,)
1272
+
1273
+ @array_function_dispatch(_require_fields_dispatcher)
1274
+ def require_fields(array, required_dtype):
1275
+ """
1276
+ Casts a structured array to a new dtype using assignment by field-name.
1277
+
1278
+ This function assigns from the old to the new array by name, so the
1279
+ value of a field in the output array is the value of the field with the
1280
+ same name in the source array. This has the effect of creating a new
1281
+ ndarray containing only the fields "required" by the required_dtype.
1282
+
1283
+ If a field name in the required_dtype does not exist in the
1284
+ input array, that field is created and set to 0 in the output array.
1285
+
1286
+ Parameters
1287
+ ----------
1288
+ a : ndarray
1289
+ array to cast
1290
+ required_dtype : dtype
1291
+ datatype for output array
1292
+
1293
+ Returns
1294
+ -------
1295
+ out : ndarray
1296
+ array with the new dtype, with field values copied from the fields in
1297
+ the input array with the same name
1298
+
1299
+ Examples
1300
+ --------
1301
+ >>> import numpy as np
1302
+
1303
+ >>> from numpy.lib import recfunctions as rfn
1304
+ >>> a = np.ones(4, dtype=[('a', 'i4'), ('b', 'f8'), ('c', 'u1')])
1305
+ >>> rfn.require_fields(a, [('b', 'f4'), ('c', 'u1')])
1306
+ array([(1., 1), (1., 1), (1., 1), (1., 1)],
1307
+ dtype=[('b', '<f4'), ('c', 'u1')])
1308
+ >>> rfn.require_fields(a, [('b', 'f4'), ('newf', 'u1')])
1309
+ array([(1., 0), (1., 0), (1., 0), (1., 0)],
1310
+ dtype=[('b', '<f4'), ('newf', 'u1')])
1311
+
1312
+ """
1313
+ out = np.empty(array.shape, dtype=required_dtype)
1314
+ assign_fields_by_name(out, array)
1315
+ return out
1316
+
1317
+
1318
+ def _stack_arrays_dispatcher(arrays, defaults=None, usemask=None,
1319
+ asrecarray=None, autoconvert=None):
1320
+ return arrays
1321
+
1322
+
1323
+ @array_function_dispatch(_stack_arrays_dispatcher)
1324
+ def stack_arrays(arrays, defaults=None, usemask=True, asrecarray=False,
1325
+ autoconvert=False):
1326
+ """
1327
+ Superposes arrays fields by fields
1328
+
1329
+ Parameters
1330
+ ----------
1331
+ arrays : array or sequence
1332
+ Sequence of input arrays.
1333
+ defaults : dictionary, optional
1334
+ Dictionary mapping field names to the corresponding default values.
1335
+ usemask : {True, False}, optional
1336
+ Whether to return a MaskedArray (or MaskedRecords is
1337
+ `asrecarray==True`) or a ndarray.
1338
+ asrecarray : {False, True}, optional
1339
+ Whether to return a recarray (or MaskedRecords if `usemask==True`)
1340
+ or just a flexible-type ndarray.
1341
+ autoconvert : {False, True}, optional
1342
+ Whether automatically cast the type of the field to the maximum.
1343
+
1344
+ Examples
1345
+ --------
1346
+ >>> import numpy as np
1347
+ >>> from numpy.lib import recfunctions as rfn
1348
+ >>> x = np.array([1, 2,])
1349
+ >>> rfn.stack_arrays(x) is x
1350
+ True
1351
+ >>> z = np.array([('A', 1), ('B', 2)], dtype=[('A', '|S3'), ('B', float)])
1352
+ >>> zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
1353
+ ... dtype=[('A', '|S3'), ('B', np.double), ('C', np.double)])
1354
+ >>> test = rfn.stack_arrays((z,zz))
1355
+ >>> test
1356
+ masked_array(data=[(b'A', 1.0, --), (b'B', 2.0, --), (b'a', 10.0, 100.0),
1357
+ (b'b', 20.0, 200.0), (b'c', 30.0, 300.0)],
1358
+ mask=[(False, False, True), (False, False, True),
1359
+ (False, False, False), (False, False, False),
1360
+ (False, False, False)],
1361
+ fill_value=(b'N/A', 1e+20, 1e+20),
1362
+ dtype=[('A', 'S3'), ('B', '<f8'), ('C', '<f8')])
1363
+
1364
+ """
1365
+ if isinstance(arrays, np.ndarray):
1366
+ return arrays
1367
+ elif len(arrays) == 1:
1368
+ return arrays[0]
1369
+ seqarrays = [np.asanyarray(a).ravel() for a in arrays]
1370
+ nrecords = [len(a) for a in seqarrays]
1371
+ ndtype = [a.dtype for a in seqarrays]
1372
+ fldnames = [d.names for d in ndtype]
1373
+ #
1374
+ dtype_l = ndtype[0]
1375
+ newdescr = _get_fieldspec(dtype_l)
1376
+ names = [n for n, d in newdescr]
1377
+ for dtype_n in ndtype[1:]:
1378
+ for fname, fdtype in _get_fieldspec(dtype_n):
1379
+ if fname not in names:
1380
+ newdescr.append((fname, fdtype))
1381
+ names.append(fname)
1382
+ else:
1383
+ nameidx = names.index(fname)
1384
+ _, cdtype = newdescr[nameidx]
1385
+ if autoconvert:
1386
+ newdescr[nameidx] = (fname, max(fdtype, cdtype))
1387
+ elif fdtype != cdtype:
1388
+ raise TypeError(f"Incompatible type '{cdtype}' <> '{fdtype}'")
1389
+ # Only one field: use concatenate
1390
+ if len(newdescr) == 1:
1391
+ output = ma.concatenate(seqarrays)
1392
+ else:
1393
+ #
1394
+ output = ma.masked_all((np.sum(nrecords),), newdescr)
1395
+ offset = np.cumsum(np.r_[0, nrecords])
1396
+ seen = []
1397
+ for (a, n, i, j) in zip(seqarrays, fldnames, offset[:-1], offset[1:]):
1398
+ names = a.dtype.names
1399
+ if names is None:
1400
+ output[f'f{len(seen)}'][i:j] = a
1401
+ else:
1402
+ for name in n:
1403
+ output[name][i:j] = a[name]
1404
+ if name not in seen:
1405
+ seen.append(name)
1406
+ #
1407
+ return _fix_output(_fix_defaults(output, defaults),
1408
+ usemask=usemask, asrecarray=asrecarray)
1409
+
1410
+
1411
+ def _find_duplicates_dispatcher(
1412
+ a, key=None, ignoremask=None, return_index=None):
1413
+ return (a,)
1414
+
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
+
1475
+ def _join_by_dispatcher(
1476
+ key, r1, r2, jointype=None, r1postfix=None, r2postfix=None,
1477
+ defaults=None, usemask=None, asrecarray=None):
1478
+ return (r1, r2)
1479
+
1480
+
1481
+ @array_function_dispatch(_join_by_dispatcher)
1482
+ def join_by(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2',
1483
+ defaults=None, usemask=True, asrecarray=False):
1484
+ """
1485
+ Join arrays `r1` and `r2` on key `key`.
1486
+
1487
+ The key should be either a string or a sequence of string corresponding
1488
+ to the fields used to join the array. An exception is raised if the
1489
+ `key` field cannot be found in the two input arrays. Neither `r1` nor
1490
+ `r2` should have any duplicates along `key`: the presence of duplicates
1491
+ will make the output quite unreliable. Note that duplicates are not
1492
+ looked for by the algorithm.
1493
+
1494
+ Parameters
1495
+ ----------
1496
+ key : {string, sequence}
1497
+ A string or a sequence of strings corresponding to the fields used
1498
+ for comparison.
1499
+ r1, r2 : arrays
1500
+ Structured arrays.
1501
+ jointype : {'inner', 'outer', 'leftouter'}, optional
1502
+ If 'inner', returns the elements common to both r1 and r2.
1503
+ If 'outer', returns the common elements as well as the elements of
1504
+ r1 not in r2 and the elements of not in r2.
1505
+ If 'leftouter', returns the common elements and the elements of r1
1506
+ not in r2.
1507
+ r1postfix : string, optional
1508
+ String appended to the names of the fields of r1 that are present
1509
+ in r2 but absent of the key.
1510
+ r2postfix : string, optional
1511
+ String appended to the names of the fields of r2 that are present
1512
+ in r1 but absent of the key.
1513
+ defaults : {dictionary}, optional
1514
+ Dictionary mapping field names to the corresponding default values.
1515
+ usemask : {True, False}, optional
1516
+ Whether to return a MaskedArray (or MaskedRecords is
1517
+ `asrecarray==True`) or a ndarray.
1518
+ asrecarray : {False, True}, optional
1519
+ Whether to return a recarray (or MaskedRecords if `usemask==True`)
1520
+ or just a flexible-type ndarray.
1521
+
1522
+ Notes
1523
+ -----
1524
+ * The output is sorted along the key.
1525
+ * A temporary array is formed by dropping the fields not in the key for
1526
+ the two arrays and concatenating the result. This array is then
1527
+ sorted, and the common entries selected. The output is constructed by
1528
+ filling the fields with the selected entries. Matching is not
1529
+ preserved if there are some duplicates...
1530
+
1531
+ """
1532
+ # Check jointype
1533
+ if jointype not in ('inner', 'outer', 'leftouter'):
1534
+ raise ValueError(
1535
+ "The 'jointype' argument should be in 'inner', "
1536
+ "'outer' or 'leftouter' (got '%s' instead)" % jointype
1537
+ )
1538
+ # If we have a single key, put it in a tuple
1539
+ if isinstance(key, str):
1540
+ key = (key,)
1541
+
1542
+ # Check the keys
1543
+ if len(set(key)) != len(key):
1544
+ dup = next(x for n, x in enumerate(key) if x in key[n + 1:])
1545
+ raise ValueError(f"duplicate join key {dup!r}")
1546
+ for name in key:
1547
+ if name not in r1.dtype.names:
1548
+ raise ValueError(f'r1 does not have key field {name!r}')
1549
+ if name not in r2.dtype.names:
1550
+ raise ValueError(f'r2 does not have key field {name!r}')
1551
+
1552
+ # Make sure we work with ravelled arrays
1553
+ r1 = r1.ravel()
1554
+ r2 = r2.ravel()
1555
+ (nb1, nb2) = (len(r1), len(r2))
1556
+ (r1names, r2names) = (r1.dtype.names, r2.dtype.names)
1557
+
1558
+ # Check the names for collision
1559
+ collisions = (set(r1names) & set(r2names)) - set(key)
1560
+ if collisions and not (r1postfix or r2postfix):
1561
+ msg = "r1 and r2 contain common names, r1postfix and r2postfix "
1562
+ msg += "can't both be empty"
1563
+ raise ValueError(msg)
1564
+
1565
+ # Make temporary arrays of just the keys
1566
+ # (use order of keys in `r1` for back-compatibility)
1567
+ key1 = [n for n in r1names if n in key]
1568
+ r1k = _keep_fields(r1, key1)
1569
+ r2k = _keep_fields(r2, key1)
1570
+
1571
+ # Concatenate the two arrays for comparison
1572
+ aux = ma.concatenate((r1k, r2k))
1573
+ idx_sort = aux.argsort(order=key)
1574
+ aux = aux[idx_sort]
1575
+ #
1576
+ # Get the common keys
1577
+ flag_in = ma.concatenate(([False], aux[1:] == aux[:-1]))
1578
+ flag_in[:-1] = flag_in[1:] + flag_in[:-1]
1579
+ idx_in = idx_sort[flag_in]
1580
+ idx_1 = idx_in[(idx_in < nb1)]
1581
+ idx_2 = idx_in[(idx_in >= nb1)] - nb1
1582
+ (r1cmn, r2cmn) = (len(idx_1), len(idx_2))
1583
+ if jointype == 'inner':
1584
+ (r1spc, r2spc) = (0, 0)
1585
+ elif jointype == 'outer':
1586
+ idx_out = idx_sort[~flag_in]
1587
+ idx_1 = np.concatenate((idx_1, idx_out[(idx_out < nb1)]))
1588
+ idx_2 = np.concatenate((idx_2, idx_out[(idx_out >= nb1)] - nb1))
1589
+ (r1spc, r2spc) = (len(idx_1) - r1cmn, len(idx_2) - r2cmn)
1590
+ elif jointype == 'leftouter':
1591
+ idx_out = idx_sort[~flag_in]
1592
+ idx_1 = np.concatenate((idx_1, idx_out[(idx_out < nb1)]))
1593
+ (r1spc, r2spc) = (len(idx_1) - r1cmn, 0)
1594
+ # Select the entries from each input
1595
+ (s1, s2) = (r1[idx_1], r2[idx_2])
1596
+ #
1597
+ # Build the new description of the output array .......
1598
+ # Start with the key fields
1599
+ ndtype = _get_fieldspec(r1k.dtype)
1600
+
1601
+ # Add the fields from r1
1602
+ for fname, fdtype in _get_fieldspec(r1.dtype):
1603
+ if fname not in key:
1604
+ ndtype.append((fname, fdtype))
1605
+
1606
+ # Add the fields from r2
1607
+ for fname, fdtype in _get_fieldspec(r2.dtype):
1608
+ # Have we seen the current name already ?
1609
+ # we need to rebuild this list every time
1610
+ names = [name for name, dtype in ndtype]
1611
+ try:
1612
+ nameidx = names.index(fname)
1613
+ except ValueError:
1614
+ #... we haven't: just add the description to the current list
1615
+ ndtype.append((fname, fdtype))
1616
+ else:
1617
+ # collision
1618
+ _, cdtype = ndtype[nameidx]
1619
+ if fname in key:
1620
+ # The current field is part of the key: take the largest dtype
1621
+ ndtype[nameidx] = (fname, max(fdtype, cdtype))
1622
+ else:
1623
+ # The current field is not part of the key: add the suffixes,
1624
+ # and place the new field adjacent to the old one
1625
+ ndtype[nameidx:nameidx + 1] = [
1626
+ (fname + r1postfix, cdtype),
1627
+ (fname + r2postfix, fdtype)
1628
+ ]
1629
+ # Rebuild a dtype from the new fields
1630
+ ndtype = np.dtype(ndtype)
1631
+ # Find the largest nb of common fields :
1632
+ # r1cmn and r2cmn should be equal, but...
1633
+ cmn = max(r1cmn, r2cmn)
1634
+ # Construct an empty array
1635
+ output = ma.masked_all((cmn + r1spc + r2spc,), dtype=ndtype)
1636
+ names = output.dtype.names
1637
+ for f in r1names:
1638
+ selected = s1[f]
1639
+ if f not in names or (f in r2names and not r2postfix and f not in key):
1640
+ f += r1postfix
1641
+ current = output[f]
1642
+ current[:r1cmn] = selected[:r1cmn]
1643
+ if jointype in ('outer', 'leftouter'):
1644
+ current[cmn:cmn + r1spc] = selected[r1cmn:]
1645
+ for f in r2names:
1646
+ selected = s2[f]
1647
+ if f not in names or (f in r1names and not r1postfix and f not in key):
1648
+ f += r2postfix
1649
+ current = output[f]
1650
+ current[:r2cmn] = selected[:r2cmn]
1651
+ if (jointype == 'outer') and r2spc:
1652
+ current[-r2spc:] = selected[r2cmn:]
1653
+ # Sort and finalize the output
1654
+ output.sort(order=key)
1655
+ kwargs = {'usemask': usemask, 'asrecarray': asrecarray}
1656
+ return _fix_output(_fix_defaults(output, defaults), **kwargs)
1657
+
1658
+
1659
+ def _rec_join_dispatcher(
1660
+ key, r1, r2, jointype=None, r1postfix=None, r2postfix=None,
1661
+ defaults=None):
1662
+ return (r1, r2)
1663
+
1664
+
1665
+ @array_function_dispatch(_rec_join_dispatcher)
1666
+ def rec_join(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2',
1667
+ defaults=None):
1668
+ """
1669
+ Join arrays `r1` and `r2` on keys.
1670
+ Alternative to join_by, that always returns a np.recarray.
1671
+
1672
+ See Also
1673
+ --------
1674
+ join_by : equivalent function
1675
+ """
1676
+ kwargs = {'jointype': jointype, 'r1postfix': r1postfix, 'r2postfix': r2postfix,
1677
+ 'defaults': defaults, 'usemask': False, 'asrecarray': True}
1678
+ return join_by(key, r1, r2, **kwargs)
1679
+
1680
+
1681
+ del array_function_dispatch