Skip to content

Tools

Tools module#

statista.tools.Tools #

Collection of statistical and data transformation utilities.

This class provides static methods for various data transformations and manipulations commonly used in statistical analysis, including normalization, standardization, rescaling, and logarithmic transformations.

All methods are implemented as static methods, so they can be called directly without instantiating the class.

Examples:

  • Import the Tools class:
    >>> import numpy as np
    >>> from statista.tools import Tools
    
  • Normalize an array to [0, 1] range
    >>> data = [10, 20, 30, 40, 50]
    >>> normalized = Tools.normalize(data)
    >>> print(normalized)
    [0.   0.25 0.5  0.75 1.  ]
    
  • Standardize an array (mean=0, std=1):
    >>> standardized = Tools.standardize(data)
    >>> print(f"Mean: {np.mean(standardized):.4f}, Std: {np.std(standardized):.4f}")
    Mean: 0.0000, Std: 1.0000
    
Source code in statista/tools.py
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
class Tools:
    """Collection of statistical and data transformation utilities.

    This class provides static methods for various data transformations and 
    manipulations commonly used in statistical analysis, including normalization,
    standardization, rescaling, and logarithmic transformations.

    All methods are implemented as static methods, so they can be called directly
    without instantiating the class.

    Examples:
        - Import the Tools class:
            ```python
            >>> import numpy as np
            >>> from statista.tools import Tools
            ```
        -  Normalize an array to [0, 1] range
            ```python
            >>> data = [10, 20, 30, 40, 50]
            >>> normalized = Tools.normalize(data)
            >>> print(normalized)
            [0.   0.25 0.5  0.75 1.  ]

            ```
        - Standardize an array (mean=0, std=1):
            ```python
            >>> standardized = Tools.standardize(data)
            >>> print(f"Mean: {np.mean(standardized):.4f}, Std: {np.std(standardized):.4f}")
            Mean: 0.0000, Std: 1.0000
            ```
    """

    def __init__(self):
        pass

    @staticmethod
    def normalize(x: Union[List[float], np.ndarray]) -> np.ndarray:
        """Normalize values to the range [0, 1].

        Scales all values in the input array to the range [0, 1] using min-max normalization.
        The formula used is: (x - min(x)) / (max(x) - min(x))

        Args:
            x: Input array or list of values to normalize.

        Returns:
            np.ndarray: Array of normalized values in the range [0, 1].

        Raises:
            ValueError: If all values in the input are identical (max = min),
                which would cause division by zero.

        Examples:
            - Normalize a list of values:
                ```python
                >>> from statista.tools import Tools
                >>> data = [10, 20, 30, 40, 50]
                >>> normalized = Tools.normalize(data)
                >>> print(normalized)
                [0.   0.25 0.5  0.75 1.  ]

                ```
            - Normalize a numpy array:
                ```python
                >>> import numpy as np
                >>> data = np.array([5, 15, 25, 35, 45])
                >>> normalized = Tools.normalize(data)
                >>> print(normalized)
                [0.   0.25 0.5  0.75 1.  ]

                ```
            - Edge case: single value:
                ```python
                >>> data = [42]
                >>> normalized = Tools.normalize(data)
                >>> print(normalized)
                [0.]

                ```

        See Also:
            - Tools.standardize: For standardizing values to mean=0, std=1
            - Tools.rescale: For rescaling values to a custom range
        """
        x = np.array(x)
        data_max = max(x)
        data_min = min(x)
        return (x - data_min) / (data_max - data_min)

    @staticmethod
    def standardize(x: Union[List[float], np.ndarray]) -> np.ndarray:
        """Standardize values to have mean=0 and standard deviation=1.

        Transforms the input array so that it has a mean of 0 and a standard deviation of 1.
        This is also known as z-score normalization or standard score.
        The formula used is: (x - mean(x)) / std(x)

        Args:
            x: Input array or list of values to standardize.

        Returns:
            np.ndarray: Array of standardized values with mean=0 and std=1.

        Raises:
            ValueError: If the standard deviation of the input is zero,
                which would cause division by zero.

        Examples:
            - Standardize a list of values:
                ```python
                >>> from statista.tools import Tools
                >>> import numpy as np
                >>> data = [10, 20, 30, 40, 50]
                >>> standardized = Tools.standardize(data)
                >>> print(f"Mean: {np.mean(standardized):.4f}, Std: {np.std(standardized):.4f}")
                Mean: 0.0000, Std: 1.0000

                ```
            - Verify the transformation:
                ```python
                >>> print(standardized)
                [-1.41421356 -0.70710678  0.          0.70710678  1.41421356]

                ```
            - Standardize values that already have mean=0:
                ```python
                >>> data = [-2, -1, 0, 1, 2]
                >>> standardized = Tools.standardize(data)
                >>> print(standardized)
                [-1.41421356 -0.70710678  0.          0.70710678  1.41421356]

                ```

        Notes:
            Standardization is particularly useful for algorithms that assume
            the data is centered around zero with unit variance, such as many
            machine learning algorithms.

        See Also:
            - Tools.normalize: For scaling values to the range [0, 1]
            - Tools.rescale: For rescaling values to a custom range
        """
        x = np.array(x)

        mean = np.mean(x)
        std = np.std(x)
        s = (x - mean) / std
        return s

    @staticmethod
    def rescale(
        old_value: float, 
        old_min: float, 
        old_max: float, 
        new_min: float, 
        new_max: float
    ) -> float:
        """Rescale a value from one range to another.

        Linearly transforms a value from its original range [old_min, old_max] 
        to a new range [new_min, new_max]. This is useful for mapping values 
        between different scales while preserving their relative positions.

        The formula used is:
        new_value = (((old_value - old_min) * (new_max - new_min)) / (old_max - old_min)) + new_min

        Args:
            old_value: The value to rescale.
            old_min: The minimum value of the original range.
            old_max: The maximum value of the original range.
            new_min: The minimum value of the target range.
            new_max: The maximum value of the target range.

        Returns:
            float: The rescaled value in the new range.

        Raises:
            ZeroDivisionError: If old_max equals old_min, causing division by zero.

        Examples:
            - Rescale a value from [0, 100] to [0, 1]:
                ```python
                >>> from statista.tools import Tools
                >>> value = 75
                >>> rescaled = Tools.rescale(value, 0, 100, 0, 1)
                >>> print(rescaled)
                0.75

                ```
            - Rescale a value from [0, 1] to [-1, 1]:
                ```python
                >>> value = 0.3
                >>> rescaled = Tools.rescale(value, 0, 1, -1, 1)
                >>> print(rescaled)
                -0.4

                ```
            - Rescale a temperature from Celsius to Fahrenheit:
                ```python
                >>> celsius = 25
                >>> fahrenheit = Tools.rescale(celsius, 0, 100, 32, 212)
                >>> print(f"{celsius}°C = {fahrenheit}°F")
                25°C = 77.0°F
                ```

        See Also:
            - Tools.normalize: For scaling values to the range [0, 1]
            - Tools.log_rescale: For logarithmic rescaling
        """
        old_range = old_max - old_min
        new_range = new_max - new_min
        new_value = (((old_value - old_min) * new_range) / old_range) + new_min

        return new_value

    @staticmethod
    def log_rescale(
        x: float, 
        min_old: float, 
        max_old: float, 
        min_new: float, 
        max_new: float
    ) -> int:
        """Rescale a value using logarithmic transformation.

        Transforms a value from its original range to a new range using logarithmic scaling.
        This is useful when dealing with data that spans multiple orders of magnitude,
        as it compresses large values and expands small values.

        The method first converts the value and boundaries to logarithmic space,
        then performs a linear rescaling in that space, and finally rounds to an integer.

        Args:
            x: The value to rescale.
            min_old: The minimum value of the original range.
            max_old: The maximum value of the original range.
            min_new: The minimum value of the target range.
            max_new: The maximum value of the target range.

        Returns:
            int: The logarithmically rescaled value as an integer in the new range.

        Raises:
            ValueError: If max_old is not greater than min_old.
            ValueError: If x is negative (logarithm undefined).

        Examples:
            - Rescale a value from [1, 1000] to [1, 10]:
                ```python
                >>> from statista.tools import Tools
                >>> value = 100
                >>> rescaled = Tools.log_rescale(value, 1, 1000, 1, 10)
                >>> print(rescaled)
                7

                ```
            - Rescale a small value:
                ```python
                >>> value = 10
                >>> rescaled = Tools.log_rescale(value, 1, 1000, 1, 10)
                >>> print(rescaled)
                4

                ```
            - Handle zero values (special case):
                ```python
                >>> value = 0
                >>> rescaled = Tools.log_rescale(value, 0, 1000, 0, 10)
                >>> print(rescaled)
                0

                ```

        Notes:
            - For x = 0, the function uses a special case handling by setting the log value to -7.
            - For min_old = 0, the function also uses -7 as the logarithmic value.
            - The base of the logarithm is e (natural logarithm).

        See Also:
            - Tools.inv_log_rescale: For inverse logarithmic rescaling
            - Tools.rescale: For linear rescaling
        """
        # get the boundaries of the logarithmic scale
        if np.isclose(min_old, 0.0):
            min_old_log = -7
        else:
            min_old_log = np.log(min_old)

        max_old_log = np.log(max_old)

        if x == 0:
            x_log = -7
        else:
            x_log = np.log(x)

        y = int(
            np.round(Tools.rescale(x_log, min_old_log, max_old_log, min_new, max_new))
        )

        return y

    @staticmethod
    def inv_log_rescale(
        x: float, 
        min_old: float, 
        max_old: float, 
        min_new: float, 
        max_new: float, 
        base: float = np.e
    ) -> int:
        """Rescale a value using inverse logarithmic transformation.

        Performs the inverse operation of log_rescale. Instead of taking logarithms,
        this method raises the base to the power of the input values before rescaling.
        This is useful when you need to expand the scale of values that were previously
        compressed using a logarithmic transformation.

        The method first converts the value and boundaries to exponential space using
        the specified base, then performs a linear rescaling in that space, and finally
        rounds to an integer.

        Args:
            x: The value to rescale.
            min_old: The minimum value of the original range.
            max_old: The maximum value of the original range.
            min_new: The minimum value of the target range.
            max_new: The maximum value of the target range.
            base: The base to use for the exponential transformation. Defaults to e (natural exponential).

        Returns:
            int: The inverse logarithmically rescaled value as an integer in the new range.

        Raises:
            ValueError: If max_old is not greater than min_old.
            OverflowError: If the exponential values are too large to handle.

        Examples:
            - Rescale a value from [1, 3] to [1, 1000] using base e:
                ```python
                >>> from statista.tools import Tools
                >>> value = 2
                >>> rescaled = Tools.inv_log_rescale(value, 1, 3, 1, 1000)
                >>> print(rescaled)
                148

                ```

            - Using a different base (base 10):
                ```python
                >>> import numpy as np
                >>> value = 1
                >>> rescaled = Tools.inv_log_rescale(value, 0, 2, 1, 100, base=10)
                >>> print(rescaled)
                10

                ```
            - Verify inverse relationship with log_rescale:
                ```python
                >>> original = 500
                ```
            - First log_rescale from [1, 1000] to [0, 3]:
                ```python
                >>> log_scaled = Tools.log_rescale(original, 1, 1000, 0, 3)

                ```
            - Then inv_log_rescale back from [0, 3] to [1, 1000]:
                ```python
                >>> back_to_original = Tools.inv_log_rescale(log_scaled, 0, 3, 1, 1000)
                >>> print(f"Original: {original}, After round-trip: {back_to_original}")
                Original: 500, After round-trip: 403

                ```

        Notes:
            Due to rounding and the discrete nature of the transformation,
            the round-trip conversion (log_rescale followed by inv_log_rescale)
            may not exactly reproduce the original value.

        See Also:
            - Tools.log_rescale: For logarithmic rescaling
            - Tools.rescale: For linear rescaling
        """
        # get the boundaries of the logarithmic scale

        min_old_power = np.power(base, min_old)
        max_old_power = np.power(base, max_old)
        x_power = np.power(base, x)

        y = int(
            np.round(
                Tools.rescale(x_power, min_old_power, max_old_power, min_new, max_new)
            )
        )
        return y

    @staticmethod
    def round(number: float, precision: float) -> float:
        """Round a number to a specified precision.

        Rounds a number to the nearest multiple of the specified precision.
        This is different from Python's built-in round function, which rounds
        to a specified number of decimal places.

        Args:
            number: The number to be rounded.
            precision: The precision to round to. For example, if precision is 0.5,
                the number will be rounded to the nearest 0.5.

        Returns:
            float: The rounded number.

        Examples:
            - Round to the nearest 0.5
            ```python
            >>> from statista.tools import Tools
            >>> value = 3.7
            >>> rounded = Tools.round(value, 0.5)
            >>> print(rounded)
            3.5

            ```

            - Round to the nearest 5:
                ```python
                >>> value = 23
                >>> rounded = Tools.round(value, 5)
                >>> print(rounded)
                25

                ```

            - Round to the nearest 0.1:
                ```python
                >>> value = 7.84
                >>> rounded = Tools.round(value, 0.1)
                >>> print(rounded)
                7.8

                ```

        Notes:
            The formula used is: round(number / precision) * precision

            This method is useful for rounding to specific increments rather than
            decimal places. For example, rounding to the nearest 0.25, 0.5, or 5.
        """
        return round(number / precision) * precision

normalize(x) staticmethod #

Normalize values to the range [0, 1].

Scales all values in the input array to the range [0, 1] using min-max normalization. The formula used is: (x - min(x)) / (max(x) - min(x))

Parameters:

Name Type Description Default
x Union[List[float], ndarray]

Input array or list of values to normalize.

required

Returns:

Type Description
ndarray

np.ndarray: Array of normalized values in the range [0, 1].

Raises:

Type Description
ValueError

If all values in the input are identical (max = min), which would cause division by zero.

Examples:

  • Normalize a list of values:
    >>> from statista.tools import Tools
    >>> data = [10, 20, 30, 40, 50]
    >>> normalized = Tools.normalize(data)
    >>> print(normalized)
    [0.   0.25 0.5  0.75 1.  ]
    
  • Normalize a numpy array:
    >>> import numpy as np
    >>> data = np.array([5, 15, 25, 35, 45])
    >>> normalized = Tools.normalize(data)
    >>> print(normalized)
    [0.   0.25 0.5  0.75 1.  ]
    
  • Edge case: single value:
    >>> data = [42]
    >>> normalized = Tools.normalize(data)
    >>> print(normalized)
    [0.]
    
See Also
  • Tools.standardize: For standardizing values to mean=0, std=1
  • Tools.rescale: For rescaling values to a custom range
Source code in statista/tools.py
@staticmethod
def normalize(x: Union[List[float], np.ndarray]) -> np.ndarray:
    """Normalize values to the range [0, 1].

    Scales all values in the input array to the range [0, 1] using min-max normalization.
    The formula used is: (x - min(x)) / (max(x) - min(x))

    Args:
        x: Input array or list of values to normalize.

    Returns:
        np.ndarray: Array of normalized values in the range [0, 1].

    Raises:
        ValueError: If all values in the input are identical (max = min),
            which would cause division by zero.

    Examples:
        - Normalize a list of values:
            ```python
            >>> from statista.tools import Tools
            >>> data = [10, 20, 30, 40, 50]
            >>> normalized = Tools.normalize(data)
            >>> print(normalized)
            [0.   0.25 0.5  0.75 1.  ]

            ```
        - Normalize a numpy array:
            ```python
            >>> import numpy as np
            >>> data = np.array([5, 15, 25, 35, 45])
            >>> normalized = Tools.normalize(data)
            >>> print(normalized)
            [0.   0.25 0.5  0.75 1.  ]

            ```
        - Edge case: single value:
            ```python
            >>> data = [42]
            >>> normalized = Tools.normalize(data)
            >>> print(normalized)
            [0.]

            ```

    See Also:
        - Tools.standardize: For standardizing values to mean=0, std=1
        - Tools.rescale: For rescaling values to a custom range
    """
    x = np.array(x)
    data_max = max(x)
    data_min = min(x)
    return (x - data_min) / (data_max - data_min)

standardize(x) staticmethod #

Standardize values to have mean=0 and standard deviation=1.

Transforms the input array so that it has a mean of 0 and a standard deviation of 1. This is also known as z-score normalization or standard score. The formula used is: (x - mean(x)) / std(x)

Parameters:

Name Type Description Default
x Union[List[float], ndarray]

Input array or list of values to standardize.

required

Returns:

Type Description
ndarray

np.ndarray: Array of standardized values with mean=0 and std=1.

Raises:

Type Description
ValueError

If the standard deviation of the input is zero, which would cause division by zero.

Examples:

  • Standardize a list of values:
    >>> from statista.tools import Tools
    >>> import numpy as np
    >>> data = [10, 20, 30, 40, 50]
    >>> standardized = Tools.standardize(data)
    >>> print(f"Mean: {np.mean(standardized):.4f}, Std: {np.std(standardized):.4f}")
    Mean: 0.0000, Std: 1.0000
    
  • Verify the transformation:
    >>> print(standardized)
    [-1.41421356 -0.70710678  0.          0.70710678  1.41421356]
    
  • Standardize values that already have mean=0:
    >>> data = [-2, -1, 0, 1, 2]
    >>> standardized = Tools.standardize(data)
    >>> print(standardized)
    [-1.41421356 -0.70710678  0.          0.70710678  1.41421356]
    
Notes

Standardization is particularly useful for algorithms that assume the data is centered around zero with unit variance, such as many machine learning algorithms.

See Also
  • Tools.normalize: For scaling values to the range [0, 1]
  • Tools.rescale: For rescaling values to a custom range
Source code in statista/tools.py
@staticmethod
def standardize(x: Union[List[float], np.ndarray]) -> np.ndarray:
    """Standardize values to have mean=0 and standard deviation=1.

    Transforms the input array so that it has a mean of 0 and a standard deviation of 1.
    This is also known as z-score normalization or standard score.
    The formula used is: (x - mean(x)) / std(x)

    Args:
        x: Input array or list of values to standardize.

    Returns:
        np.ndarray: Array of standardized values with mean=0 and std=1.

    Raises:
        ValueError: If the standard deviation of the input is zero,
            which would cause division by zero.

    Examples:
        - Standardize a list of values:
            ```python
            >>> from statista.tools import Tools
            >>> import numpy as np
            >>> data = [10, 20, 30, 40, 50]
            >>> standardized = Tools.standardize(data)
            >>> print(f"Mean: {np.mean(standardized):.4f}, Std: {np.std(standardized):.4f}")
            Mean: 0.0000, Std: 1.0000

            ```
        - Verify the transformation:
            ```python
            >>> print(standardized)
            [-1.41421356 -0.70710678  0.          0.70710678  1.41421356]

            ```
        - Standardize values that already have mean=0:
            ```python
            >>> data = [-2, -1, 0, 1, 2]
            >>> standardized = Tools.standardize(data)
            >>> print(standardized)
            [-1.41421356 -0.70710678  0.          0.70710678  1.41421356]

            ```

    Notes:
        Standardization is particularly useful for algorithms that assume
        the data is centered around zero with unit variance, such as many
        machine learning algorithms.

    See Also:
        - Tools.normalize: For scaling values to the range [0, 1]
        - Tools.rescale: For rescaling values to a custom range
    """
    x = np.array(x)

    mean = np.mean(x)
    std = np.std(x)
    s = (x - mean) / std
    return s

rescale(old_value, old_min, old_max, new_min, new_max) staticmethod #

Rescale a value from one range to another.

Linearly transforms a value from its original range [old_min, old_max] to a new range [new_min, new_max]. This is useful for mapping values between different scales while preserving their relative positions.

The formula used is: new_value = (((old_value - old_min) * (new_max - new_min)) / (old_max - old_min)) + new_min

Parameters:

Name Type Description Default
old_value float

The value to rescale.

required
old_min float

The minimum value of the original range.

required
old_max float

The maximum value of the original range.

required
new_min float

The minimum value of the target range.

required
new_max float

The maximum value of the target range.

required

Returns:

Name Type Description
float float

The rescaled value in the new range.

Raises:

Type Description
ZeroDivisionError

If old_max equals old_min, causing division by zero.

Examples:

  • Rescale a value from [0, 100] to [0, 1]:
    >>> from statista.tools import Tools
    >>> value = 75
    >>> rescaled = Tools.rescale(value, 0, 100, 0, 1)
    >>> print(rescaled)
    0.75
    
  • Rescale a value from [0, 1] to [-1, 1]:
    >>> value = 0.3
    >>> rescaled = Tools.rescale(value, 0, 1, -1, 1)
    >>> print(rescaled)
    -0.4
    
  • Rescale a temperature from Celsius to Fahrenheit:
    >>> celsius = 25
    >>> fahrenheit = Tools.rescale(celsius, 0, 100, 32, 212)
    >>> print(f"{celsius}°C = {fahrenheit}°F")
    25°C = 77.0°F
    
See Also
  • Tools.normalize: For scaling values to the range [0, 1]
  • Tools.log_rescale: For logarithmic rescaling
Source code in statista/tools.py
@staticmethod
def rescale(
    old_value: float, 
    old_min: float, 
    old_max: float, 
    new_min: float, 
    new_max: float
) -> float:
    """Rescale a value from one range to another.

    Linearly transforms a value from its original range [old_min, old_max] 
    to a new range [new_min, new_max]. This is useful for mapping values 
    between different scales while preserving their relative positions.

    The formula used is:
    new_value = (((old_value - old_min) * (new_max - new_min)) / (old_max - old_min)) + new_min

    Args:
        old_value: The value to rescale.
        old_min: The minimum value of the original range.
        old_max: The maximum value of the original range.
        new_min: The minimum value of the target range.
        new_max: The maximum value of the target range.

    Returns:
        float: The rescaled value in the new range.

    Raises:
        ZeroDivisionError: If old_max equals old_min, causing division by zero.

    Examples:
        - Rescale a value from [0, 100] to [0, 1]:
            ```python
            >>> from statista.tools import Tools
            >>> value = 75
            >>> rescaled = Tools.rescale(value, 0, 100, 0, 1)
            >>> print(rescaled)
            0.75

            ```
        - Rescale a value from [0, 1] to [-1, 1]:
            ```python
            >>> value = 0.3
            >>> rescaled = Tools.rescale(value, 0, 1, -1, 1)
            >>> print(rescaled)
            -0.4

            ```
        - Rescale a temperature from Celsius to Fahrenheit:
            ```python
            >>> celsius = 25
            >>> fahrenheit = Tools.rescale(celsius, 0, 100, 32, 212)
            >>> print(f"{celsius}°C = {fahrenheit}°F")
            25°C = 77.0°F
            ```

    See Also:
        - Tools.normalize: For scaling values to the range [0, 1]
        - Tools.log_rescale: For logarithmic rescaling
    """
    old_range = old_max - old_min
    new_range = new_max - new_min
    new_value = (((old_value - old_min) * new_range) / old_range) + new_min

    return new_value

log_rescale(x, min_old, max_old, min_new, max_new) staticmethod #

Rescale a value using logarithmic transformation.

Transforms a value from its original range to a new range using logarithmic scaling. This is useful when dealing with data that spans multiple orders of magnitude, as it compresses large values and expands small values.

The method first converts the value and boundaries to logarithmic space, then performs a linear rescaling in that space, and finally rounds to an integer.

Parameters:

Name Type Description Default
x float

The value to rescale.

required
min_old float

The minimum value of the original range.

required
max_old float

The maximum value of the original range.

required
min_new float

The minimum value of the target range.

required
max_new float

The maximum value of the target range.

required

Returns:

Name Type Description
int int

The logarithmically rescaled value as an integer in the new range.

Raises:

Type Description
ValueError

If max_old is not greater than min_old.

ValueError

If x is negative (logarithm undefined).

Examples:

  • Rescale a value from [1, 1000] to [1, 10]:
    >>> from statista.tools import Tools
    >>> value = 100
    >>> rescaled = Tools.log_rescale(value, 1, 1000, 1, 10)
    >>> print(rescaled)
    7
    
  • Rescale a small value:
    >>> value = 10
    >>> rescaled = Tools.log_rescale(value, 1, 1000, 1, 10)
    >>> print(rescaled)
    4
    
  • Handle zero values (special case):
    >>> value = 0
    >>> rescaled = Tools.log_rescale(value, 0, 1000, 0, 10)
    >>> print(rescaled)
    0
    
Notes
  • For x = 0, the function uses a special case handling by setting the log value to -7.
  • For min_old = 0, the function also uses -7 as the logarithmic value.
  • The base of the logarithm is e (natural logarithm).
See Also
  • Tools.inv_log_rescale: For inverse logarithmic rescaling
  • Tools.rescale: For linear rescaling
Source code in statista/tools.py
@staticmethod
def log_rescale(
    x: float, 
    min_old: float, 
    max_old: float, 
    min_new: float, 
    max_new: float
) -> int:
    """Rescale a value using logarithmic transformation.

    Transforms a value from its original range to a new range using logarithmic scaling.
    This is useful when dealing with data that spans multiple orders of magnitude,
    as it compresses large values and expands small values.

    The method first converts the value and boundaries to logarithmic space,
    then performs a linear rescaling in that space, and finally rounds to an integer.

    Args:
        x: The value to rescale.
        min_old: The minimum value of the original range.
        max_old: The maximum value of the original range.
        min_new: The minimum value of the target range.
        max_new: The maximum value of the target range.

    Returns:
        int: The logarithmically rescaled value as an integer in the new range.

    Raises:
        ValueError: If max_old is not greater than min_old.
        ValueError: If x is negative (logarithm undefined).

    Examples:
        - Rescale a value from [1, 1000] to [1, 10]:
            ```python
            >>> from statista.tools import Tools
            >>> value = 100
            >>> rescaled = Tools.log_rescale(value, 1, 1000, 1, 10)
            >>> print(rescaled)
            7

            ```
        - Rescale a small value:
            ```python
            >>> value = 10
            >>> rescaled = Tools.log_rescale(value, 1, 1000, 1, 10)
            >>> print(rescaled)
            4

            ```
        - Handle zero values (special case):
            ```python
            >>> value = 0
            >>> rescaled = Tools.log_rescale(value, 0, 1000, 0, 10)
            >>> print(rescaled)
            0

            ```

    Notes:
        - For x = 0, the function uses a special case handling by setting the log value to -7.
        - For min_old = 0, the function also uses -7 as the logarithmic value.
        - The base of the logarithm is e (natural logarithm).

    See Also:
        - Tools.inv_log_rescale: For inverse logarithmic rescaling
        - Tools.rescale: For linear rescaling
    """
    # get the boundaries of the logarithmic scale
    if np.isclose(min_old, 0.0):
        min_old_log = -7
    else:
        min_old_log = np.log(min_old)

    max_old_log = np.log(max_old)

    if x == 0:
        x_log = -7
    else:
        x_log = np.log(x)

    y = int(
        np.round(Tools.rescale(x_log, min_old_log, max_old_log, min_new, max_new))
    )

    return y

inv_log_rescale(x, min_old, max_old, min_new, max_new, base=np.e) staticmethod #

Rescale a value using inverse logarithmic transformation.

Performs the inverse operation of log_rescale. Instead of taking logarithms, this method raises the base to the power of the input values before rescaling. This is useful when you need to expand the scale of values that were previously compressed using a logarithmic transformation.

The method first converts the value and boundaries to exponential space using the specified base, then performs a linear rescaling in that space, and finally rounds to an integer.

Parameters:

Name Type Description Default
x float

The value to rescale.

required
min_old float

The minimum value of the original range.

required
max_old float

The maximum value of the original range.

required
min_new float

The minimum value of the target range.

required
max_new float

The maximum value of the target range.

required
base float

The base to use for the exponential transformation. Defaults to e (natural exponential).

e

Returns:

Name Type Description
int int

The inverse logarithmically rescaled value as an integer in the new range.

Raises:

Type Description
ValueError

If max_old is not greater than min_old.

OverflowError

If the exponential values are too large to handle.

Examples:

  • Rescale a value from [1, 3] to [1, 1000] using base e:

    >>> from statista.tools import Tools
    >>> value = 2
    >>> rescaled = Tools.inv_log_rescale(value, 1, 3, 1, 1000)
    >>> print(rescaled)
    148
    

  • Using a different base (base 10):

    >>> import numpy as np
    >>> value = 1
    >>> rescaled = Tools.inv_log_rescale(value, 0, 2, 1, 100, base=10)
    >>> print(rescaled)
    10
    

  • Verify inverse relationship with log_rescale:
    >>> original = 500
    
  • First log_rescale from [1, 1000] to [0, 3]:
    >>> log_scaled = Tools.log_rescale(original, 1, 1000, 0, 3)
    
  • Then inv_log_rescale back from [0, 3] to [1, 1000]:
    >>> back_to_original = Tools.inv_log_rescale(log_scaled, 0, 3, 1, 1000)
    >>> print(f"Original: {original}, After round-trip: {back_to_original}")
    Original: 500, After round-trip: 403
    
Notes

Due to rounding and the discrete nature of the transformation, the round-trip conversion (log_rescale followed by inv_log_rescale) may not exactly reproduce the original value.

See Also
  • Tools.log_rescale: For logarithmic rescaling
  • Tools.rescale: For linear rescaling
Source code in statista/tools.py
@staticmethod
def inv_log_rescale(
    x: float, 
    min_old: float, 
    max_old: float, 
    min_new: float, 
    max_new: float, 
    base: float = np.e
) -> int:
    """Rescale a value using inverse logarithmic transformation.

    Performs the inverse operation of log_rescale. Instead of taking logarithms,
    this method raises the base to the power of the input values before rescaling.
    This is useful when you need to expand the scale of values that were previously
    compressed using a logarithmic transformation.

    The method first converts the value and boundaries to exponential space using
    the specified base, then performs a linear rescaling in that space, and finally
    rounds to an integer.

    Args:
        x: The value to rescale.
        min_old: The minimum value of the original range.
        max_old: The maximum value of the original range.
        min_new: The minimum value of the target range.
        max_new: The maximum value of the target range.
        base: The base to use for the exponential transformation. Defaults to e (natural exponential).

    Returns:
        int: The inverse logarithmically rescaled value as an integer in the new range.

    Raises:
        ValueError: If max_old is not greater than min_old.
        OverflowError: If the exponential values are too large to handle.

    Examples:
        - Rescale a value from [1, 3] to [1, 1000] using base e:
            ```python
            >>> from statista.tools import Tools
            >>> value = 2
            >>> rescaled = Tools.inv_log_rescale(value, 1, 3, 1, 1000)
            >>> print(rescaled)
            148

            ```

        - Using a different base (base 10):
            ```python
            >>> import numpy as np
            >>> value = 1
            >>> rescaled = Tools.inv_log_rescale(value, 0, 2, 1, 100, base=10)
            >>> print(rescaled)
            10

            ```
        - Verify inverse relationship with log_rescale:
            ```python
            >>> original = 500
            ```
        - First log_rescale from [1, 1000] to [0, 3]:
            ```python
            >>> log_scaled = Tools.log_rescale(original, 1, 1000, 0, 3)

            ```
        - Then inv_log_rescale back from [0, 3] to [1, 1000]:
            ```python
            >>> back_to_original = Tools.inv_log_rescale(log_scaled, 0, 3, 1, 1000)
            >>> print(f"Original: {original}, After round-trip: {back_to_original}")
            Original: 500, After round-trip: 403

            ```

    Notes:
        Due to rounding and the discrete nature of the transformation,
        the round-trip conversion (log_rescale followed by inv_log_rescale)
        may not exactly reproduce the original value.

    See Also:
        - Tools.log_rescale: For logarithmic rescaling
        - Tools.rescale: For linear rescaling
    """
    # get the boundaries of the logarithmic scale

    min_old_power = np.power(base, min_old)
    max_old_power = np.power(base, max_old)
    x_power = np.power(base, x)

    y = int(
        np.round(
            Tools.rescale(x_power, min_old_power, max_old_power, min_new, max_new)
        )
    )
    return y

round(number, precision) staticmethod #

Round a number to a specified precision.

Rounds a number to the nearest multiple of the specified precision. This is different from Python's built-in round function, which rounds to a specified number of decimal places.

Parameters:

Name Type Description Default
number float

The number to be rounded.

required
precision float

The precision to round to. For example, if precision is 0.5, the number will be rounded to the nearest 0.5.

required

Returns:

Name Type Description
float float

The rounded number.

Examples:

  • Round to the nearest 0.5

    >>> from statista.tools import Tools
    >>> value = 3.7
    >>> rounded = Tools.round(value, 0.5)
    >>> print(rounded)
    3.5
    

  • Round to the nearest 5:

    >>> value = 23
    >>> rounded = Tools.round(value, 5)
    >>> print(rounded)
    25
    

  • Round to the nearest 0.1:

    >>> value = 7.84
    >>> rounded = Tools.round(value, 0.1)
    >>> print(rounded)
    7.8
    

Notes

The formula used is: round(number / precision) * precision

This method is useful for rounding to specific increments rather than decimal places. For example, rounding to the nearest 0.25, 0.5, or 5.

Source code in statista/tools.py
@staticmethod
def round(number: float, precision: float) -> float:
    """Round a number to a specified precision.

    Rounds a number to the nearest multiple of the specified precision.
    This is different from Python's built-in round function, which rounds
    to a specified number of decimal places.

    Args:
        number: The number to be rounded.
        precision: The precision to round to. For example, if precision is 0.5,
            the number will be rounded to the nearest 0.5.

    Returns:
        float: The rounded number.

    Examples:
        - Round to the nearest 0.5
        ```python
        >>> from statista.tools import Tools
        >>> value = 3.7
        >>> rounded = Tools.round(value, 0.5)
        >>> print(rounded)
        3.5

        ```

        - Round to the nearest 5:
            ```python
            >>> value = 23
            >>> rounded = Tools.round(value, 5)
            >>> print(rounded)
            25

            ```

        - Round to the nearest 0.1:
            ```python
            >>> value = 7.84
            >>> rounded = Tools.round(value, 0.1)
            >>> print(rounded)
            7.8

            ```

    Notes:
        The formula used is: round(number / precision) * precision

        This method is useful for rounding to specific increments rather than
        decimal places. For example, rounding to the nearest 0.25, 0.5, or 5.
    """
    return round(number / precision) * precision