reciprocalspaceship 1.0.1__tar.gz → 1.0.3__tar.gz
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.
Potentially problematic release.
This version of reciprocalspaceship might be problematic. Click here for more details.
- {reciprocalspaceship-1.0.1/reciprocalspaceship.egg-info → reciprocalspaceship-1.0.3}/PKG-INFO +2 -5
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/README.md +1 -1
- reciprocalspaceship-1.0.3/reciprocalspaceship/VERSION +1 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/__init__.py +9 -2
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/algorithms/scale_merged_intensities.py +8 -7
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dataset.py +28 -3
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/decorators.py +8 -4
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/floating.py +24 -28
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/integer.py +38 -37
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/internals.py +243 -49
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/io/__init__.py +1 -0
- reciprocalspaceship-1.0.3/reciprocalspaceship/io/common.py +48 -0
- reciprocalspaceship-1.0.3/reciprocalspaceship/io/crystfel.py +595 -0
- reciprocalspaceship-1.0.3/reciprocalspaceship/io/dials.py +330 -0
- reciprocalspaceship-1.0.3/reciprocalspaceship/io/dials_mpi.py +44 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/io/mtz.py +4 -5
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/__init__.py +6 -1
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/cell.py +5 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/stats.py +5 -7
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/structurefactors.py +5 -0
- reciprocalspaceship-1.0.3/reciprocalspaceship/utils/units.py +19 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3/reciprocalspaceship.egg-info}/PKG-INFO +2 -5
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship.egg-info/SOURCES.txt +4 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship.egg-info/entry_points.txt +0 -1
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship.egg-info/requires.txt +4 -2
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/setup.py +5 -4
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_dataseries.py +1 -1
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_dataset.py +42 -0
- reciprocalspaceship-1.0.3/tests/test_dataset_signatures.py +53 -0
- reciprocalspaceship-1.0.1/reciprocalspaceship/VERSION +0 -1
- reciprocalspaceship-1.0.1/reciprocalspaceship/io/crystfel.py +0 -270
- reciprocalspaceship-1.0.1/reciprocalspaceship/utils/units.py +0 -9
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/LICENSE +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/MANIFEST.in +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/algorithms/__init__.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/algorithms/intensity.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/algorithms/merge.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/commandline/__init__.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/commandline/mtzdump.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/concat.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dataseries.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/__init__.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/base.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/inference.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/summarize.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/io/ccp4map.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/io/csv.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/io/pickle.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/io/precognition.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/stats/__init__.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/stats/completeness.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/asu.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/binning.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/grid.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/math.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/phases.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/rfree.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/utils/symmetry.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship.egg-info/dependency_links.txt +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship.egg-info/top_level.txt +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/setup.cfg +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/__init__.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/conftest.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_dataset_anomalous.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_dataset_binning.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_dataset_grid.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_dataset_index.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_dataset_preserve_attributes.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_dataset_symops.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_decorators.py +0 -0
- {reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/tests/test_summarize_mtz_dtypes.py +0 -0
{reciprocalspaceship-1.0.1/reciprocalspaceship.egg-info → reciprocalspaceship-1.0.3}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: reciprocalspaceship
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: Tools for exploring reciprocal space
|
|
5
5
|
Home-page: https://rs-station.github.io/reciprocalspaceship/
|
|
6
6
|
Author: Kevin M. Dalton, Jack B. Greisman
|
|
@@ -9,7 +9,6 @@ License: MIT
|
|
|
9
9
|
Project-URL: Bug Tracker, https://github.com/rs-station/reciprocalspaceship/issues
|
|
10
10
|
Project-URL: Documentation, https://rs-station.github.io/reciprocalspaceship/
|
|
11
11
|
Project-URL: Source Code, https://github.com/rs-station/reciprocalspaceship
|
|
12
|
-
Platform: UNKNOWN
|
|
13
12
|
Classifier: Development Status :: 3 - Alpha
|
|
14
13
|
Classifier: Intended Audience :: Developers
|
|
15
14
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -18,7 +17,7 @@ Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
|
18
17
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
18
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
19
|
Classifier: Programming Language :: Python
|
|
21
|
-
Requires-Python:
|
|
20
|
+
Requires-Python: >=3.9
|
|
22
21
|
Provides-Extra: dev
|
|
23
22
|
Provides-Extra: examples
|
|
24
23
|
License-File: LICENSE
|
|
@@ -42,5 +41,3 @@ Features of this library include:
|
|
|
42
41
|
use space groups, unit cell parameters, and crystallographic symmetry
|
|
43
42
|
operations.
|
|
44
43
|
- Support for reading and writing MTZ reflection files.
|
|
45
|
-
|
|
46
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 1
|
|
1
|
+
# 1 / 🚀 = reciprocalspaceship
|
|
2
2
|

|
|
3
3
|
[](https://rs-station.github.io/reciprocalspaceship)
|
|
4
4
|
[](https://pypi.org/project/reciprocalspaceship/)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.3
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# Version number for reciprocalspaceship
|
|
2
2
|
def getVersionNumber():
|
|
3
|
-
|
|
3
|
+
version = None
|
|
4
|
+
try:
|
|
5
|
+
from setuptools.version import metadata
|
|
6
|
+
|
|
7
|
+
version = metadata.version("reciprocalspaceship")
|
|
8
|
+
except ImportError:
|
|
9
|
+
from setuptools.version import pkg_resources
|
|
10
|
+
|
|
11
|
+
version = pkg_resources.require("reciprocalspaceship")[0].version
|
|
4
12
|
|
|
5
|
-
version = pkg_resources.require("reciprocalspaceship")[0].version
|
|
6
13
|
return version
|
|
7
14
|
|
|
8
15
|
|
|
@@ -185,6 +185,7 @@ def scale_merged_intensities(
|
|
|
185
185
|
mean_intensity_method="isotropic",
|
|
186
186
|
bins=100,
|
|
187
187
|
bw=2.0,
|
|
188
|
+
minimum_sigma=-np.inf,
|
|
188
189
|
):
|
|
189
190
|
"""
|
|
190
191
|
Scales merged intensities using Bayesian statistics in order to
|
|
@@ -240,6 +241,9 @@ def scale_merged_intensities(
|
|
|
240
241
|
parameter controls the distance that each reflection impacts in
|
|
241
242
|
reciprocal space. Only affects output if mean_intensity_method is
|
|
242
243
|
\"anisotropic\".
|
|
244
|
+
minimum_sigma : float
|
|
245
|
+
Minimum value imposed on Sigma (default: -np.inf, that is: no minimum).
|
|
246
|
+
|
|
243
247
|
|
|
244
248
|
Returns
|
|
245
249
|
-------
|
|
@@ -281,14 +285,11 @@ def scale_merged_intensities(
|
|
|
281
285
|
I, Sig = ds[intensity_key].to_numpy(), ds[sigma_key].to_numpy()
|
|
282
286
|
if mean_intensity_method == "isotropic":
|
|
283
287
|
dHKL = ds["dHKL"].to_numpy(dtype=np.float64)
|
|
284
|
-
Sigma = (
|
|
285
|
-
mean_intensity_by_resolution(I / multiplicity, dHKL, bins) * multiplicity
|
|
286
|
-
)
|
|
288
|
+
Sigma = mean_intensity_by_resolution(I / multiplicity, dHKL, bins)
|
|
287
289
|
elif mean_intensity_method == "anisotropic":
|
|
288
|
-
Sigma = (
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
)
|
|
290
|
+
Sigma = mean_intensity_by_miller_index(I / multiplicity, ds.get_hkls(), bw)
|
|
291
|
+
Sigma = np.clip(Sigma, a_min=minimum_sigma, a_max=np.inf)
|
|
292
|
+
Sigma = Sigma * multiplicity
|
|
292
293
|
|
|
293
294
|
# Initialize outputs
|
|
294
295
|
ds[outputI] = 0.0
|
|
@@ -258,7 +258,14 @@ class DataSet(pd.DataFrame):
|
|
|
258
258
|
)
|
|
259
259
|
|
|
260
260
|
def reset_index(
|
|
261
|
-
self,
|
|
261
|
+
self,
|
|
262
|
+
level=None,
|
|
263
|
+
drop=False,
|
|
264
|
+
inplace=False,
|
|
265
|
+
col_level=0,
|
|
266
|
+
col_fill="",
|
|
267
|
+
allow_duplicates=lib.no_default,
|
|
268
|
+
names=None,
|
|
262
269
|
):
|
|
263
270
|
"""
|
|
264
271
|
Reset the index or a specific level of a MultiIndex.
|
|
@@ -281,6 +288,12 @@ class DataSet(pd.DataFrame):
|
|
|
281
288
|
col_fill : object
|
|
282
289
|
If the columns have multiple levels, determines how the other
|
|
283
290
|
levels are named. If None then the index name is repeated.
|
|
291
|
+
allow_duplicates : bool
|
|
292
|
+
Allow duplicate column labels to be created.
|
|
293
|
+
names : int, str, tuple, list
|
|
294
|
+
Using the given string, rename the DataSet column which contains the
|
|
295
|
+
index data. If the DataSet has a MultiIndex, this has to be a list or
|
|
296
|
+
tuple with length equal to the number of levels.
|
|
284
297
|
|
|
285
298
|
Returns
|
|
286
299
|
-------
|
|
@@ -317,6 +330,8 @@ class DataSet(pd.DataFrame):
|
|
|
317
330
|
inplace=inplace,
|
|
318
331
|
col_level=col_level,
|
|
319
332
|
col_fill=col_fill,
|
|
333
|
+
allow_duplicates=allow_duplicates,
|
|
334
|
+
names=names,
|
|
320
335
|
)
|
|
321
336
|
_handle_cached_dtypes(self, columns, drop)
|
|
322
337
|
return
|
|
@@ -327,6 +342,8 @@ class DataSet(pd.DataFrame):
|
|
|
327
342
|
inplace=inplace,
|
|
328
343
|
col_level=col_level,
|
|
329
344
|
col_fill=col_fill,
|
|
345
|
+
allow_duplicates=allow_duplicates,
|
|
346
|
+
names=names,
|
|
330
347
|
)
|
|
331
348
|
dataset._index_dtypes = dataset._index_dtypes.copy()
|
|
332
349
|
dataset = _handle_cached_dtypes(dataset, columns, drop)
|
|
@@ -406,6 +423,7 @@ class DataSet(pd.DataFrame):
|
|
|
406
423
|
"""
|
|
407
424
|
return cls(gemmiMtz)
|
|
408
425
|
|
|
426
|
+
@range_indexed
|
|
409
427
|
def to_gemmi(
|
|
410
428
|
self,
|
|
411
429
|
skip_problem_mtztypes=False,
|
|
@@ -575,6 +593,7 @@ class DataSet(pd.DataFrame):
|
|
|
575
593
|
result = super().join(*args, **kwargs)
|
|
576
594
|
return result.__finalize__(self)
|
|
577
595
|
|
|
596
|
+
@range_indexed
|
|
578
597
|
def write_mtz(
|
|
579
598
|
self,
|
|
580
599
|
mtzfile,
|
|
@@ -1158,7 +1177,7 @@ class DataSet(pd.DataFrame):
|
|
|
1158
1177
|
|
|
1159
1178
|
return result
|
|
1160
1179
|
|
|
1161
|
-
def is_isomorphous(self, other, cell_threshold=0.
|
|
1180
|
+
def is_isomorphous(self, other, cell_threshold=0.5):
|
|
1162
1181
|
"""
|
|
1163
1182
|
Determine whether DataSet is isomorphous to another DataSet. This
|
|
1164
1183
|
method confirms isomorphism by ensuring the spacegroups are equivalent,
|
|
@@ -1195,7 +1214,8 @@ class DataSet(pd.DataFrame):
|
|
|
1195
1214
|
for param in params:
|
|
1196
1215
|
param1 = self.cell.__getattribute__(param)
|
|
1197
1216
|
param2 = other.cell.__getattribute__(param)
|
|
1198
|
-
|
|
1217
|
+
diff = 200.0 * np.abs(param1 - param2) / (param1 + param2)
|
|
1218
|
+
if diff > cell_threshold:
|
|
1199
1219
|
return False
|
|
1200
1220
|
|
|
1201
1221
|
return True
|
|
@@ -1234,6 +1254,11 @@ class DataSet(pd.DataFrame):
|
|
|
1234
1254
|
# Compute new HKLs and phase shifts
|
|
1235
1255
|
hkls = dataset.get_hkls()
|
|
1236
1256
|
compressed_hkls, inverse = np.unique(hkls, axis=0, return_inverse=True)
|
|
1257
|
+
|
|
1258
|
+
# The behavior of np.unique changed with v2.0. This block maintains v1 compatibility
|
|
1259
|
+
if inverse.shape[-1] == 1:
|
|
1260
|
+
inverse = inverse.squeeze(-1)
|
|
1261
|
+
|
|
1237
1262
|
asu_hkls, isym, phi_coeff, phi_shift = hkl_to_asu(
|
|
1238
1263
|
compressed_hkls, dataset.spacegroup, return_phase_shifts=True
|
|
1239
1264
|
)
|
|
@@ -4,6 +4,8 @@ from inspect import signature
|
|
|
4
4
|
import gemmi
|
|
5
5
|
import numpy as np
|
|
6
6
|
|
|
7
|
+
import reciprocalspaceship as rs
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
def inplace(f):
|
|
9
11
|
"""
|
|
@@ -46,9 +48,11 @@ def range_indexed(f):
|
|
|
46
48
|
names = ds.index.names
|
|
47
49
|
ds = ds._index_from_names([None], inplace=True)
|
|
48
50
|
result = f(ds, *args, **kwargs)
|
|
49
|
-
result = result._index_from_names(names, inplace=True)
|
|
50
51
|
ds = ds._index_from_names(names, inplace=True)
|
|
51
|
-
|
|
52
|
+
if isinstance(result, rs.DataSet):
|
|
53
|
+
result = result._index_from_names(names, inplace=True)
|
|
54
|
+
result = result.__finalize__(ds)
|
|
55
|
+
return result
|
|
52
56
|
|
|
53
57
|
return wrapped
|
|
54
58
|
|
|
@@ -100,7 +104,7 @@ def spacegroupify(func=None, *sg_args):
|
|
|
100
104
|
for arg in sg_args:
|
|
101
105
|
if arg in bargs.arguments:
|
|
102
106
|
bargs.arguments[arg] = _convert_spacegroup(bargs.arguments[arg])
|
|
103
|
-
return f(**bargs.
|
|
107
|
+
return f(*bargs.args, **bargs.kwargs)
|
|
104
108
|
|
|
105
109
|
return wrapped
|
|
106
110
|
|
|
@@ -155,7 +159,7 @@ def cellify(func=None, *cell_args):
|
|
|
155
159
|
for arg in cell_args:
|
|
156
160
|
if arg in bargs.arguments:
|
|
157
161
|
bargs.arguments[arg] = _convert_unitcell(bargs.arguments[arg])
|
|
158
|
-
return f(**bargs.
|
|
162
|
+
return f(*bargs.args, **bargs.kwargs)
|
|
159
163
|
|
|
160
164
|
return wrapped
|
|
161
165
|
|
{reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/floating.py
RENAMED
|
@@ -34,7 +34,6 @@ from __future__ import annotations
|
|
|
34
34
|
|
|
35
35
|
import numpy as np
|
|
36
36
|
from pandas._libs import lib
|
|
37
|
-
from pandas._libs import missing as libmissing
|
|
38
37
|
from pandas._typing import ArrayLike, DtypeObj
|
|
39
38
|
from pandas.util._decorators import cache_readonly
|
|
40
39
|
|
|
@@ -45,6 +44,7 @@ except:
|
|
|
45
44
|
|
|
46
45
|
from pandas import Float32Dtype, Float64Dtype
|
|
47
46
|
from pandas.core.arrays import ExtensionArray
|
|
47
|
+
from pandas.core.dtypes.cast import np_find_common_type
|
|
48
48
|
from pandas.core.dtypes.common import (
|
|
49
49
|
is_bool_dtype,
|
|
50
50
|
is_float,
|
|
@@ -58,7 +58,7 @@ from pandas.core.dtypes.dtypes import ExtensionDtype, register_extension_dtype
|
|
|
58
58
|
from pandas.core.tools.numeric import to_numeric
|
|
59
59
|
|
|
60
60
|
from reciprocalspaceship.dtypes.base import MTZDtype
|
|
61
|
-
from reciprocalspaceship.dtypes.internals import NumericArray
|
|
61
|
+
from reciprocalspaceship.dtypes.internals import NumericArray, is_numeric_na
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
class MTZFloat32Dtype(MTZDtype):
|
|
@@ -80,14 +80,14 @@ class MTZFloat32Dtype(MTZDtype):
|
|
|
80
80
|
return self
|
|
81
81
|
if not all(isinstance(t, MTZFloat32Dtype) for t in dtypes):
|
|
82
82
|
return None
|
|
83
|
-
np_dtype =
|
|
83
|
+
np_dtype = np_find_common_type(
|
|
84
84
|
# error: Item "ExtensionDtype" of "Union[Any, ExtensionDtype]" has no
|
|
85
85
|
# attribute "numpy_dtype"
|
|
86
86
|
[t.numpy_dtype for t in dtypes], # type: ignore[union-attr]
|
|
87
87
|
[],
|
|
88
88
|
)
|
|
89
89
|
if np.issubdtype(np_dtype, np.floating):
|
|
90
|
-
return
|
|
90
|
+
return Float32Dtype()
|
|
91
91
|
return None
|
|
92
92
|
|
|
93
93
|
|
|
@@ -136,7 +136,11 @@ def coerce_to_array(
|
|
|
136
136
|
mask = mask.copy()
|
|
137
137
|
return values, mask
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
if copy:
|
|
140
|
+
values = np.array(values, copy=copy)
|
|
141
|
+
else:
|
|
142
|
+
values = np.asarray(values)
|
|
143
|
+
|
|
140
144
|
if is_object_dtype(values.dtype):
|
|
141
145
|
inferred_type = lib.infer_dtype(values, skipna=True)
|
|
142
146
|
if inferred_type == "empty":
|
|
@@ -160,7 +164,7 @@ def coerce_to_array(
|
|
|
160
164
|
raise TypeError("values must be a 1D list-like")
|
|
161
165
|
|
|
162
166
|
if mask is None:
|
|
163
|
-
mask =
|
|
167
|
+
mask = is_numeric_na(values)
|
|
164
168
|
|
|
165
169
|
else:
|
|
166
170
|
assert len(mask) == len(values)
|
|
@@ -286,6 +290,20 @@ class MTZFloatArray(NumericArray):
|
|
|
286
290
|
def _coerce_to_array(self, value) -> tuple[np.ndarray, np.ndarray]:
|
|
287
291
|
return coerce_to_array(value, dtype=self.dtype)
|
|
288
292
|
|
|
293
|
+
def _maybe_mask_result(self, result, mask):
|
|
294
|
+
"""
|
|
295
|
+
Parameters
|
|
296
|
+
----------
|
|
297
|
+
result : array-like
|
|
298
|
+
mask : array-like bool
|
|
299
|
+
"""
|
|
300
|
+
# if we have a float operand we are by-definition
|
|
301
|
+
# a float result
|
|
302
|
+
# or our op is a divide
|
|
303
|
+
if result.dtype.kind == "f":
|
|
304
|
+
return type(self)(result, mask, copy=False)
|
|
305
|
+
return super()._maybe_mask_result(result=result, mask=mask)
|
|
306
|
+
|
|
289
307
|
def astype(self, dtype, copy: bool = True) -> ArrayLike:
|
|
290
308
|
"""
|
|
291
309
|
Cast to a NumPy array or ExtensionArray with 'dtype'.
|
|
@@ -328,28 +346,6 @@ class MTZFloatArray(NumericArray):
|
|
|
328
346
|
data = self.to_numpy(dtype=dtype, **kwargs) # type: ignore[arg-type]
|
|
329
347
|
return astype_nansafe(data, dtype, copy=False)
|
|
330
348
|
|
|
331
|
-
def _maybe_mask_result(self, result, mask, other, op_name: str):
|
|
332
|
-
"""
|
|
333
|
-
Parameters
|
|
334
|
-
----------
|
|
335
|
-
result : array-like
|
|
336
|
-
mask : array-like bool
|
|
337
|
-
other : scalar or array-like
|
|
338
|
-
op_name : str
|
|
339
|
-
"""
|
|
340
|
-
# if we have a float operand we are by-definition
|
|
341
|
-
# a float result
|
|
342
|
-
# or our op is a divide
|
|
343
|
-
if (
|
|
344
|
-
(is_float_dtype(other) or is_float(other))
|
|
345
|
-
or (op_name in ["rtruediv", "truediv"])
|
|
346
|
-
or (is_float_dtype(self.dtype) and is_numeric_dtype(result.dtype))
|
|
347
|
-
):
|
|
348
|
-
return type(self)(result, mask, copy=False)
|
|
349
|
-
return super()._maybe_mask_result(
|
|
350
|
-
result=result, mask=mask, other=other, op_name=op_name
|
|
351
|
-
)
|
|
352
|
-
|
|
353
349
|
def _values_for_argsort(self) -> np.ndarray:
|
|
354
350
|
return self._data
|
|
355
351
|
|
{reciprocalspaceship-1.0.1 → reciprocalspaceship-1.0.3}/reciprocalspaceship/dtypes/integer.py
RENAMED
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
from __future__ import annotations
|
|
34
34
|
|
|
35
35
|
import numpy as np
|
|
36
|
-
from pandas import Int32Dtype, Int64Dtype
|
|
36
|
+
from pandas import Float32Dtype, Int32Dtype, Int64Dtype
|
|
37
37
|
from pandas._libs import lib
|
|
38
|
-
from pandas._libs import missing as libmissing
|
|
39
38
|
from pandas._typing import ArrayLike, Dtype, DtypeObj
|
|
40
39
|
from pandas.core.arrays import ExtensionArray
|
|
41
40
|
from pandas.core.dtypes.base import ExtensionDtype, register_extension_dtype
|
|
41
|
+
from pandas.core.dtypes.cast import np_find_common_type
|
|
42
42
|
from pandas.core.dtypes.common import (
|
|
43
43
|
is_bool_dtype,
|
|
44
44
|
is_float_dtype,
|
|
@@ -51,7 +51,11 @@ from pandas.core.tools.numeric import to_numeric
|
|
|
51
51
|
from pandas.util._decorators import cache_readonly
|
|
52
52
|
|
|
53
53
|
from reciprocalspaceship.dtypes.base import MTZDtype
|
|
54
|
-
from reciprocalspaceship.dtypes.internals import
|
|
54
|
+
from reciprocalspaceship.dtypes.internals import (
|
|
55
|
+
BaseMaskedDtype,
|
|
56
|
+
NumericArray,
|
|
57
|
+
is_numeric_na,
|
|
58
|
+
)
|
|
55
59
|
|
|
56
60
|
|
|
57
61
|
class MTZInt32Dtype(MTZDtype):
|
|
@@ -88,25 +92,25 @@ class MTZInt32Dtype(MTZDtype):
|
|
|
88
92
|
for t in dtypes
|
|
89
93
|
):
|
|
90
94
|
return None
|
|
91
|
-
np_dtype =
|
|
95
|
+
np_dtype = np_find_common_type(
|
|
92
96
|
# error: List comprehension has incompatible type List[Union[Any,
|
|
93
97
|
# dtype, ExtensionDtype]]; expected List[Union[dtype, None, type,
|
|
94
98
|
# _SupportsDtype, str, Tuple[Any, Union[int, Sequence[int]]],
|
|
95
99
|
# List[Any], _DtypeDict, Tuple[Any, Any]]]
|
|
96
100
|
[
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
101
|
+
(
|
|
102
|
+
t.numpy_dtype # type: ignore[misc]
|
|
103
|
+
if isinstance(t, BaseMaskedDtype)
|
|
104
|
+
else t
|
|
105
|
+
)
|
|
100
106
|
for t in dtypes
|
|
101
107
|
],
|
|
102
108
|
[],
|
|
103
109
|
)
|
|
104
110
|
if np.issubdtype(np_dtype, np.integer):
|
|
105
|
-
return
|
|
111
|
+
return Int32Dtype()
|
|
106
112
|
elif np.issubdtype(np_dtype, np.floating):
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return FLOAT_STR_TO_DTYPE[str(np_dtype)]
|
|
113
|
+
return Float32Dtype()
|
|
110
114
|
return None
|
|
111
115
|
|
|
112
116
|
|
|
@@ -175,7 +179,11 @@ def coerce_to_array(
|
|
|
175
179
|
mask = mask.copy()
|
|
176
180
|
return values, mask
|
|
177
181
|
|
|
178
|
-
|
|
182
|
+
if copy:
|
|
183
|
+
values = np.array(values, copy=copy)
|
|
184
|
+
else:
|
|
185
|
+
values = np.asarray(values)
|
|
186
|
+
|
|
179
187
|
inferred_type = None
|
|
180
188
|
if is_object_dtype(values.dtype) or is_string_dtype(values.dtype):
|
|
181
189
|
inferred_type = lib.infer_dtype(values, skipna=True)
|
|
@@ -202,7 +210,7 @@ def coerce_to_array(
|
|
|
202
210
|
raise TypeError("values must be a 1D list-like")
|
|
203
211
|
|
|
204
212
|
if mask is None:
|
|
205
|
-
mask =
|
|
213
|
+
mask = is_numeric_na(values)
|
|
206
214
|
else:
|
|
207
215
|
assert len(mask) == len(values)
|
|
208
216
|
|
|
@@ -227,7 +235,12 @@ def coerce_to_array(
|
|
|
227
235
|
# a ValueError if the str cannot be parsed into an int
|
|
228
236
|
values = values.astype(dtype, copy=copy)
|
|
229
237
|
else:
|
|
230
|
-
|
|
238
|
+
try:
|
|
239
|
+
values = safe_cast(values, dtype, copy=False)
|
|
240
|
+
except:
|
|
241
|
+
# certain outputs cannot be coerced to int32
|
|
242
|
+
dtype = np.dtype("float64")
|
|
243
|
+
values = safe_cast(values, dtype, copy=False)
|
|
231
244
|
|
|
232
245
|
return values, mask
|
|
233
246
|
|
|
@@ -310,14 +323,6 @@ class MTZIntegerArray(NumericArray):
|
|
|
310
323
|
def dtype(self) -> MTZInt32Dtype:
|
|
311
324
|
return self._dtype
|
|
312
325
|
|
|
313
|
-
def __init__(self, values: np.ndarray, mask: np.ndarray, copy: bool = False):
|
|
314
|
-
if not (isinstance(values, np.ndarray) and values.dtype.kind in ["i", "u"]):
|
|
315
|
-
raise TypeError(
|
|
316
|
-
"values should be integer numpy array. Use "
|
|
317
|
-
"the 'pd.array' function instead"
|
|
318
|
-
)
|
|
319
|
-
super().__init__(values, mask, copy=copy)
|
|
320
|
-
|
|
321
326
|
@classmethod
|
|
322
327
|
def _from_sequence(
|
|
323
328
|
cls, scalars, *, dtype: Dtype | None = None, copy: bool = False
|
|
@@ -335,6 +340,17 @@ class MTZIntegerArray(NumericArray):
|
|
|
335
340
|
def _coerce_to_array(self, value) -> tuple[np.ndarray, np.ndarray]:
|
|
336
341
|
return coerce_to_array(value, dtype=self.dtype)
|
|
337
342
|
|
|
343
|
+
def _maybe_mask_result(self, result, mask):
|
|
344
|
+
"""
|
|
345
|
+
Parameters
|
|
346
|
+
----------
|
|
347
|
+
result : array-like
|
|
348
|
+
mask : array-like bool
|
|
349
|
+
"""
|
|
350
|
+
if result.dtype.kind in "iu":
|
|
351
|
+
return type(self)(result, mask, copy=False)
|
|
352
|
+
return super()._maybe_mask_result(result=result, mask=mask)
|
|
353
|
+
|
|
338
354
|
def astype(self, dtype, copy: bool = True) -> ArrayLike:
|
|
339
355
|
"""
|
|
340
356
|
Cast to a NumPy array or ExtensionArray with 'dtype'.
|
|
@@ -375,21 +391,6 @@ class MTZIntegerArray(NumericArray):
|
|
|
375
391
|
|
|
376
392
|
return self.to_numpy(dtype=dtype, na_value=na_value, copy=False)
|
|
377
393
|
|
|
378
|
-
def _maybe_mask_result(self, result, mask, other, op_name: str):
|
|
379
|
-
"""
|
|
380
|
-
Parameters
|
|
381
|
-
----------
|
|
382
|
-
result : array-like
|
|
383
|
-
mask : array-like bool
|
|
384
|
-
other : scalar or array-like
|
|
385
|
-
op_name : str
|
|
386
|
-
"""
|
|
387
|
-
if is_integer_dtype(result):
|
|
388
|
-
return type(self)(result, mask, copy=False)
|
|
389
|
-
return super()._maybe_mask_result(
|
|
390
|
-
result=result, mask=mask, other=other, op_name=op_name
|
|
391
|
-
)
|
|
392
|
-
|
|
393
394
|
def _values_for_argsort(self) -> np.ndarray:
|
|
394
395
|
"""
|
|
395
396
|
Return values for sorting.
|