### 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