PyLab surprises/inconsistencies

There is a number of "features" that make numpy very difficult to use. One can excuse these inconsistencies as features but they are usually just a source for confusion. A number of such cases is described here that make adopting numpy difficult.

Slicing

Numpy array slicing returns views on existing arrays. Some  of the views are real views, some of the are not, consider the following example:

>>> a = arange(10)
>>> a[2] = 1
array([0, 1, 1, 3, 4, 5, 6, 7, 8, 9])
>>> b = a[2]
>>> b[:] = 22
Exceptions.TypeError
>>> b = a[2:3]
>>> b[:] = 22
>>> a
array([ 0,  1, 22,  3,  4,  5,  6,  7,  8,  9])

The fact that using slices and numerical indices result in different types is very confusing. One might call it a feature but a very confusing one. Consider the following:

a = eye(5)
>>> a[2:4,2:4]
[[1 0]
 [0 1]]
>>> a[[2,3],[2,3]]
[1 1]

The index expression looks equivalent. But,

>> a[[2,3],:]
[[0 0 1 0 0]
 [0 0 0 1 0]]

Are we really supposed to write a[[2,3]][:,[2,3]], so ugly.
Sometimes the index refers to a slice along its dimension (1st index for a column) but sometimes for a single entry in the dimension.

Vector transpose

Why does arange(10).T == arange(). Numpy is a numerical package not a C or FORTRAN array package. Is there a definition for transpose of a n-dimensional array? The "transpose" function of numpy and the property ".T" seem to simply reverse the order of dimensions

Interface of functions

Examples speak for themselves:

>>> zeros(3).shape
(3,)
>>> eye(3).shape
(3,3)
>>> eye(1,2).shape
(1,2)
>>> eye([1,2]).shape
Error
>>> zeros([3,3]).shape
(3,3)
>>> rand(3, 3).shape
(3,3)

FORTRAN memory layout

The ".flat" property returns a flat "C" array even for a FORTRAN array. It is intended and documented, but

>>> a = ndarray([4,3,2], 'i4', order='C')
>>> a.flat[:] = arange(24)
>>> a
[[[ 0  1]
  [ 2  3]
  [ 4  5]]
...
  [22 23]]]
>>> cast(a.ctypes,POINTER(c_int))[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

and for a FORTRAN array,

>>> a = ndarray([4,3,2], 'i4', order='FORTRAN')
>>> a.flat[:] = arange(24)
>>> a
[[[ 0  1]
  [ 2  3]
  [ 4  5]]
...
  [22 23]]]
>>> cast(a.ctypes,POINTER(c_int))[:10]
[0, 6, 12, 18, 2, 8, 14, 20, 4, 10]

In FORTRAN the meaning of indices is [rows, cols, d3, d4, ...] in numpy it is the opposite [..., d4, d3, rows, cols]. The FORTRAN flag has nothing to do with it because the indexing has to be consistent.

What does "asfortranarray" do?

>>> a = asfortranarray(arange(24)).reshape(2,3,4)
>>> a.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
>>> a = asfortranarray(zeros([2,3,4])).reshape(2,3,4)
>>> a.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True

Comments