comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/doc/structured_arrays.py @ 87:2a2c65a20a8b

Add Python libs and headers
author Chris Cannam
date Wed, 25 Feb 2015 14:05:22 +0000
parents
children
comparison
equal deleted inserted replaced
86:413a9d26189e 87:2a2c65a20a8b
1 """
2 =====================================
3 Structured Arrays (and 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, f2, 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,...,float16, 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 = np.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 >>> x
149 array([(0, 0.0), (0, 0.0), (0, 0.0)],
150 dtype=[(('title 1', 'col1'), '|i1'), (('title 2', 'col2'), '>f4')])
151
152 Accessing and modifying field names
153 ===================================
154
155 The field names are an attribute of the dtype object defining the record structure.
156 For the last example: ::
157
158 >>> x.dtype.names
159 ('col1', 'col2')
160 >>> x.dtype.names = ('x', 'y')
161 >>> x
162 array([(0, 0.0), (0, 0.0), (0, 0.0)],
163 dtype=[(('title 1', 'x'), '|i1'), (('title 2', 'y'), '>f4')])
164 >>> x.dtype.names = ('x', 'y', 'z') # wrong number of names
165 <type 'exceptions.ValueError'>: must replace all names at once with a sequence of length 2
166
167 Accessing field titles
168 ====================================
169
170 The field titles provide a standard place to put associated info for fields.
171 They do not have to be strings. ::
172
173 >>> x.dtype.fields['x'][2]
174 'title 1'
175
176 Accessing multiple fields at once
177 ====================================
178
179 You can access multiple fields at once using a list of field names: ::
180
181 >>> x = np.array([(1.5,2.5,(1.0,2.0)),(3.,4.,(4.,5.)),(1.,3.,(2.,6.))],
182 dtype=[('x','f4'),('y',np.float32),('value','f4',(2,2))])
183
184 Notice that `x` is created with a list of tuples. ::
185
186 >>> x[['x','y']]
187 array([(1.5, 2.5), (3.0, 4.0), (1.0, 3.0)],
188 dtype=[('x', '<f4'), ('y', '<f4')])
189 >>> x[['x','value']]
190 array([(1.5, [[1.0, 2.0], [1.0, 2.0]]), (3.0, [[4.0, 5.0], [4.0, 5.0]]),
191 (1.0, [[2.0, 6.0], [2.0, 6.0]])],
192 dtype=[('x', '<f4'), ('value', '<f4', (2, 2))])
193
194 The fields are returned in the order they are asked for.::
195
196 >>> x[['y','x']]
197 array([(2.5, 1.5), (4.0, 3.0), (3.0, 1.0)],
198 dtype=[('y', '<f4'), ('x', '<f4')])
199
200 Filling structured arrays
201 =========================
202
203 Structured arrays can be filled by field or row by row. ::
204
205 >>> arr = np.zeros((5,), dtype=[('var1','f8'),('var2','f8')])
206 >>> arr['var1'] = np.arange(5)
207
208 If you fill it in row by row, it takes a take a tuple
209 (but not a list or array!)::
210
211 >>> arr[0] = (10,20)
212 >>> arr
213 array([(10.0, 20.0), (1.0, 0.0), (2.0, 0.0), (3.0, 0.0), (4.0, 0.0)],
214 dtype=[('var1', '<f8'), ('var2', '<f8')])
215
216 More information
217 ====================================
218 You can find some more information on recarrays and structured arrays
219 (including the difference between the two) `here
220 <http://www.scipy.org/Cookbook/Recarray>`_.
221
222 """
223 from __future__ import division, absolute_import, print_function