NumPy data type comparison

2024/11/13 14:05:49

I was playing with comparing data types of two different arrays to pick one that is suitable for combining the two. I was happy to discover that I could perform comparison operations, but in the process discovered the following strange behavior:

In [1]: numpy.int16 > numpy.float32
Out[1]: TrueIn [2]: numpy.dtype('int16') > numpy.dtype('float32')
Out[2]: False

Can anyone explain what is going on here? This is NumPy 1.8.2.

Answer

The first comparison is not meaningful, the second is meaningful.

With numpy.int16 > numpy.float32 we are comparing two type objects:

>>> type(numpy.int16)
type
>>> numpy.int16 > numpy.float32 # I'm using Python 3
TypeError: unorderable types: type() > type()

In Python 3 this comparison fails immediately since there is no defined ordering for type instances. In Python 2, a boolean is returned but cannot be relied upon for consistency (it falls back to comparing memory addresses or other implementation-level stuff).

The second comparison does work in Python 3, and it works consistently (same in Python 2). This is because we're now comparing dtype instances:

>>> type(numpy.dtype('int16'))
numpy.dtype
>>> numpy.dtype('int16') > numpy.dtype('float32')
False
>>> numpy.dtype('int32') < numpy.dtype('|S10')
False
>>> numpy.dtype('int32') < numpy.dtype('|S11')
True

What's the logic behind this ordering?

dtype instances are ordered according to whether one can be cast (safely) to another. One type is less than another if it can be safely cast to that type.

For the implementation of the comparison operators, look at descriptor.c; specifically at the arraydescr_richcompare function.

Here's what the < operator maps to:

switch (cmp_op) {case Py_LT:if (!PyArray_EquivTypes(self, new) && PyArray_CanCastTo(self, new)) {result = Py_True;}else {result = Py_False;}break;

Essentially, NumPy just checks that the two types are (i) not equivalent, and (ii) that the first type can be cast to the second type.

This functionality is also exposed in the NumPy API as np.can_cast:

>>> np.can_cast('int32', '|S10')
False
>>> np.can_cast('int32', '|S11')
True
https://en.xdnf.cn/q/72076.html

Related Q&A

A simple method for rotating images in reportlab

How can we easily rotate an image using reportlab? I have not found an easy method. The only way found comes from http://dods.ipsl.jussieu.fr/orchidee/SANORCHIDEE/TEMP/TEMP_LOCAL/cdat_portable/lib_new…

XML header getting removed after processing with elementtree

i have an xml file and i used Elementtree to add a new tag to the xml file.My xml file before processing is as follows <?xml version="1.0" encoding="utf-8"?><PackageInfo …

How to ntp server time down to millisecond precision using Python ntplib?

I am creating a python module that will output the time from a selection of NTP Pool servers to millisecond precision as an exercise in showing how server timestamps vary. Thus far I have been able to …

Control 2 separate Excel instances by COM independently... can it be done?

Ive got a legacy application which is implemented in a number of Excel workbooks. Its not something that I have the authority to re-implement, however another application that I do maintain does need t…

nested Python numpy arrays dimension confusion

Suppose I have a numpy array c constructed as follows:a = np.zeros((2,4)) b = np.zeros((2,8)) c = np.array([a,b])I would have expected c.shape to be (2,1) or (2,) but instead it is (2,2). Additionally,…

how to reuse tests written using unittest.testcase

Ive written some tests using unittest as below and I want to reuse them in another class where Im stuck and need help.. Code snippets are as below.MyTestClass.pyClass MyTestClass(unittest.TestCase): …

Randomized stratified k-fold cross-validation in scikit-learn?

Is there any built-in way to get scikit-learn to perform shuffled stratified k-fold cross-validation? This is one of the most common CV methods, and I am surprised I couldnt find a built-in method to …

Find all paths through a tree (nested dicts) from top to bottom

EDIT: See below for a suggested answer and how its not quite right yet.There are many similar questions to this one on Stack Overflow, but none exactly like it in Python. Im a programming novice, so pl…

How to show process state (blocking, non-blocking) in Linux

Is there a way to query the state of processes in a Linux process table to be able to demonstrate if a process is running or blocked at the time the query is executed? My goal is to do this from outsi…

Removing quotation marks from list items

I am running this program:f = open( "animals.txt", "r") g = f.read() g1 = g.split(,) #turning the file into list print g1And I want this to come out:[ELDEN, DORSEY, DARELL, BRODERIC…