Statistics
| Revision:

gvsig-3d / 1.10 / trunk / binaries / mac / raster / gdal / GDAL.framework / Versions / 1.7 / Python / site-packages / numpy / doc / structured_arrays.py @ 27

History | View | Annotate | Download (7.04 KB)

1
"""
2
=====================================
3
Structured Arrays (aka Record Arrays)
4
=====================================
5

6
Introduction
7
============
8

9
Numpy provides powerful capabilities to create arrays of structs or records.
10
These arrays permit one to manipulate the data by the structs or by fields of
11
the struct. A simple example will show what is meant.: ::
12

13
 >>> x = np.zeros((2,),dtype=('i4,f4,a10'))
14
 >>> x[:] = [(1,2.,'Hello'),(2,3.,"World")]
15
 >>> x
16
 array([(1, 2.0, 'Hello'), (2, 3.0, 'World')],
17
      dtype=[('f0', '>i4'), ('f1', '>f4'), ('f2', '|S10')])
18

19
Here we have created a one-dimensional array of length 2. Each element of
20
this array is a record that contains three items, a 32-bit integer, a 32-bit
21
float, and a string of length 10 or less. If we index this array at the second
22
position we get the second record: ::
23

24
 >>> x[1]
25
 (2,3.,"World")
26

27
Conveniently, one can access any field of the array by indexing using the
28
string that names that field. In this case the fields have received the
29
default names 'f0', 'f1' and 'f2'.
30

31
 >>> y = x['f1']
32
 >>> y
33
 array([ 2.,  3.], dtype=float32)
34
 >>> y[:] = 2*y
35
 >>> y
36
 array([ 4.,  6.], dtype=float32)
37
 >>> x
38
 array([(1, 4.0, 'Hello'), (2, 6.0, 'World')],
39
       dtype=[('f0', '>i4'), ('f1', '>f4'), ('f2', '|S10')])
40

41
In these examples, y is a simple float array consisting of the 2nd field
42
in the record. But, rather than being a copy of the data in the structured
43
array, it is a view, i.e., it shares exactly the same memory locations.
44
Thus, when we updated this array by doubling its values, the structured
45
array shows the corresponding values as doubled as well. Likewise, if one
46
changes the record, the field view also changes: ::
47

48
 >>> x[1] = (-1,-1.,"Master")
49
 >>> x
50
 array([(1, 4.0, 'Hello'), (-1, -1.0, 'Master')],
51
       dtype=[('f0', '>i4'), ('f1', '>f4'), ('f2', '|S10')])
52
 >>> y
53
 array([ 4., -1.], dtype=float32)
54

55
Defining Structured Arrays
56
==========================
57

58
One defines a structured array through the dtype object.  There are
59
**several** alternative ways to define the fields of a record.  Some of
60
these variants provide backward compatibility with Numeric, numarray, or
61
another module, and should not be used except for such purposes. These
62
will be so noted. One specifies record structure in
63
one of four alternative ways, using an argument (as supplied to a dtype
64
function keyword or a dtype object constructor itself).  This
65
argument must be one of the following: 1) string, 2) tuple, 3) list, or
66
4) dictionary.  Each of these is briefly described below.
67

68
1) String argument (as used in the above examples).
69
In this case, the constructor expects a comma-separated list of type
70
specifiers, optionally with extra shape information.
71
The type specifiers can take 4 different forms: ::
72

73
  a) b1, i1, i2, i4, i8, u1, u2, u4, u8, f4, f8, c8, c16, a<n>
74
     (representing bytes, ints, unsigned ints, floats, complex and
75
      fixed length strings of specified byte lengths)
76
  b) int8,...,uint8,...,float32, float64, complex64, complex128
77
     (this time with bit sizes)
78
  c) older Numeric/numarray type specifications (e.g. Float32).
79
     Don't use these in new code!
80
  d) Single character type specifiers (e.g H for unsigned short ints).
81
     Avoid using these unless you must. Details can be found in the
82
     Numpy book
83

84
These different styles can be mixed within the same string (but why would you
85
want to do that?). Furthermore, each type specifier can be prefixed
86
with a repetition number, or a shape. In these cases an array
87
element is created, i.e., an array within a record. That array
88
is still referred to as a single field. An example: ::
89

90
 >>> x = np.zeros(3, dtype='3int8, float32, (2,3)float64')
91
 >>> x
92
 array([([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
93
        ([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
94
        ([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])],
95
       dtype=[('f0', '|i1', 3), ('f1', '>f4'), ('f2', '>f8', (2, 3))])
96

97
By using strings to define the record structure, it precludes being
98
able to name the fields in the original definition. The names can
99
be changed as shown later, however.
100

101
2) Tuple argument: The only relevant tuple case that applies to record
102
structures is when a structure is mapped to an existing data type. This
103
is done by pairing in a tuple, the existing data type with a matching
104
dtype definition (using any of the variants being described here). As
105
an example (using a definition using a list, so see 3) for further
106
details): ::
107

108
 >>> x = zeros(3, dtype=('i4',[('r','u1'), ('g','u1'), ('b','u1'), ('a','u1')]))
109
 >>> x
110
 array([0, 0, 0])
111
 >>> x['r']
112
 array([0, 0, 0], dtype=uint8)
113

114
In this case, an array is produced that looks and acts like a simple int32 array,
115
but also has definitions for fields that use only one byte of the int32 (a bit
116
like Fortran equivalencing).
117

118
3) List argument: In this case the record structure is defined with a list of
119
tuples. Each tuple has 2 or 3 elements specifying: 1) The name of the field
120
('' is permitted), 2) the type of the field, and 3) the shape (optional).
121
For example:
122

123
 >>> x = np.zeros(3, dtype=[('x','f4'),('y',np.float32),('value','f4',(2,2))])
124
 >>> x
125
 array([(0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]]),
126
        (0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]]),
127
        (0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]])],
128
       dtype=[('x', '>f4'), ('y', '>f4'), ('value', '>f4', (2, 2))])
129

130
4) Dictionary argument: two different forms are permitted. The first consists
131
of a dictionary with two required keys ('names' and 'formats'), each having an
132
equal sized list of values. The format list contains any type/shape specifier
133
allowed in other contexts. The names must be strings. There are two optional
134
keys: 'offsets' and 'titles'. Each must be a correspondingly matching list to
135
the required two where offsets contain integer offsets for each field, and
136
titles are objects containing metadata for each field (these do not have
137
to be strings), where the value of None is permitted. As an example: ::
138

139
 >>> x = np.zeros(3, dtype={'names':['col1', 'col2'], 'formats':['i4','f4']})
140
 >>> x
141
 array([(0, 0.0), (0, 0.0), (0, 0.0)],
142
       dtype=[('col1', '>i4'), ('col2', '>f4')])
143

144
The other dictionary form permitted is a dictionary of name keys with tuple
145
values specifying type, offset, and an optional title.
146

147
 >>> x = np.zeros(3, dtype={'col1':('i1',0,'title 1'), 'col2':('f4',1,'title 2')})
148
 array([(0, 0.0), (0, 0.0), (0, 0.0)],
149
       dtype=[(('title 1', 'col1'), '|i1'), (('title 2', 'col2'), '>f4')])
150

151
Accessing and modifying field names
152
===================================
153

154
The field names are an attribute of the dtype object defining the record structure.
155
For the last example: ::
156

157
 >>> x.dtype.names
158
 ('col1', 'col2')
159
 >>> x.dtype.names = ('x', 'y')
160
 >>> x
161
 array([(0, 0.0), (0, 0.0), (0, 0.0)],
162
      dtype=[(('title 1', 'x'), '|i1'), (('title 2', 'y'), '>f4')])
163
 >>> x.dtype.names = ('x', 'y', 'z') # wrong number of names
164
 <type 'exceptions.ValueError'>: must replace all names at once with a sequence of length 2
165

166
Accessing field titles
167
====================================
168

169
The field titles provide a standard place to put associated info for fields.
170
They do not have to be strings.
171

172
 >>> x.dtype.fields['x'][2]
173
 'title 1'
174

175
"""