FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
patsy/patsy/user_util.py at master · Python-Repository-Hub/patsy · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
Python-Repository-Hub
/
patsy
Public
forked from
pydata/patsy
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
patsy
/
patsy
/
user_util.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
245 lines (200 loc) · 8.87 KB
Breadcrumbs
patsy
/
patsy
/
user_util.py
Copy path
File metadata and controls
245 lines (200 loc) · 8.87 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# This file is part of Patsy
# Copyright (C) 2012 Nathaniel Smith <njs@pobox.com>
# See file LICENSE.txt for license information.
# Miscellaneous utilities that are useful to users (as compared to
# patsy.util, which is misc. utilities useful for implementing patsy).
# These are made available in the patsy.* namespace
__all__
=
[
"balanced"
,
"demo_data"
,
"LookupFactor"
]
import
itertools
import
numpy
as
np
from
patsy
import
PatsyError
from
patsy
.
categorical
import
C
from
patsy
.
util
import
no_pickling
,
assert_no_pickling
def
balanced
(
**
kwargs
):
"""balanced(factor_name=num_levels, [factor_name=num_levels, ..., repeat=1])
Create simple balanced factorial designs for testing.
Given some factor names and the number of desired levels for each,
generates a balanced factorial design in the form of a data
dictionary. For example:
.. ipython::
In [1]: balanced(a=2, b=3)
Out[1]:
{'a': ['a1', 'a1', 'a1', 'a2', 'a2', 'a2'],
'b': ['b1', 'b2', 'b3', 'b1', 'b2', 'b3']}
By default it produces exactly one instance of each combination of levels,
but if you want multiple replicates this can be accomplished via the
`repeat` argument:
.. ipython::
In [2]: balanced(a=2, b=2, repeat=2)
Out[2]:
{'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'],
'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2']}
"""
repeat
=
kwargs
.
pop
(
"repeat"
,
1
)
levels
=
[]
names
=
sorted
(
kwargs
)
for
name
in
names
:
level_count
=
kwargs
[
name
]
levels
.
append
([
"%s%s"
%
(
name
,
i
)
for
i
in
range
(
1
,
level_count
+
1
)])
# zip(*...) does an "unzip"
values
=
zip
(
*
itertools
.
product
(
*
levels
))
data
=
{}
for
name
,
value
in
zip
(
names
,
values
):
data
[
name
]
=
list
(
value
)
*
repeat
return
data
def
test_balanced
():
data
=
balanced
(
a
=
2
,
b
=
3
)
assert
data
[
"a"
]
==
[
"a1"
,
"a1"
,
"a1"
,
"a2"
,
"a2"
,
"a2"
]
assert
data
[
"b"
]
==
[
"b1"
,
"b2"
,
"b3"
,
"b1"
,
"b2"
,
"b3"
]
data
=
balanced
(
a
=
2
,
b
=
3
,
repeat
=
2
)
assert
data
[
"a"
]
==
[
"a1"
,
"a1"
,
"a1"
,
"a2"
,
"a2"
,
"a2"
,
"a1"
,
"a1"
,
"a1"
,
"a2"
,
"a2"
,
"a2"
]
assert
data
[
"b"
]
==
[
"b1"
,
"b2"
,
"b3"
,
"b1"
,
"b2"
,
"b3"
,
"b1"
,
"b2"
,
"b3"
,
"b1"
,
"b2"
,
"b3"
]
def
demo_data
(
*
names
,
**
kwargs
):
"""demo_data(*names, nlevels=2, min_rows=5)
Create simple categorical/numerical demo data.
Pass in a set of variable names, and this function will return a simple
data set using those variable names.
Names whose first letter falls in the range "a" through "m" will be made
categorical (with `nlevels` levels). Those that start with a "p" through
"z" are numerical.
We attempt to produce a balanced design on the categorical variables,
repeating as necessary to generate at least `min_rows` data
points. Categorical variables are returned as a list of strings.
Numerical data is generated by sampling from a normal distribution. A
fixed random seed is used, so that identical calls to demo_data() will
produce identical results. Numerical data is returned in a numpy array.
Example:
.. ipython:
In [1]: patsy.demo_data("a", "b", "x", "y")
Out[1]:
{'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'],
'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2'],
'x': array([ 1.76405235, 0.40015721, 0.97873798, 2.2408932 ,
1.86755799, -0.97727788, 0.95008842, -0.15135721]),
'y': array([-0.10321885, 0.4105985 , 0.14404357, 1.45427351,
0.76103773, 0.12167502, 0.44386323, 0.33367433])}
"""
nlevels
=
kwargs
.
pop
(
"nlevels"
,
2
)
min_rows
=
kwargs
.
pop
(
"min_rows"
,
5
)
if
kwargs
:
raise
TypeError
(
"unexpected keyword arguments %r"
%
(
kwargs
,))
numerical
=
set
()
categorical
=
{}
for
name
in
names
:
if
name
[
0
]
in
"abcdefghijklmn"
:
categorical
[
name
]
=
nlevels
elif
name
[
0
]
in
"pqrstuvwxyz"
:
numerical
.
add
(
name
)
else
:
raise
PatsyError
(
"bad name %r"
%
(
name
,))
balanced_design_size
=
np
.
prod
(
list
(
categorical
.
values
()),
dtype
=
int
)
repeat
=
int
(
np
.
ceil
(
min_rows
*
1.0
/
balanced_design_size
))
num_rows
=
repeat
*
balanced_design_size
data
=
balanced
(
repeat
=
repeat
,
**
categorical
)
r
=
np
.
random
.
RandomState
(
0
)
for
name
in
sorted
(
numerical
):
data
[
name
]
=
r
.
normal
(
size
=
num_rows
)
return
data
def
test_demo_data
():
d1
=
demo_data
(
"a"
,
"b"
,
"x"
)
assert
sorted
(
d1
.
keys
())
==
[
"a"
,
"b"
,
"x"
]
assert
d1
[
"a"
]
==
[
"a1"
,
"a1"
,
"a2"
,
"a2"
,
"a1"
,
"a1"
,
"a2"
,
"a2"
]
assert
d1
[
"b"
]
==
[
"b1"
,
"b2"
,
"b1"
,
"b2"
,
"b1"
,
"b2"
,
"b1"
,
"b2"
]
assert
d1
[
"x"
].
dtype
==
np
.
dtype
(
float
)
assert
d1
[
"x"
].
shape
==
(
8
,)
d2
=
demo_data
(
"x"
,
"y"
)
assert
sorted
(
d2
.
keys
())
==
[
"x"
,
"y"
]
assert
len
(
d2
[
"x"
])
==
len
(
d2
[
"y"
])
==
5
assert
len
(
demo_data
(
"x"
,
min_rows
=
10
)[
"x"
])
==
10
assert
len
(
demo_data
(
"a"
,
"b"
,
"x"
,
min_rows
=
10
)[
"x"
])
==
12
assert
len
(
demo_data
(
"a"
,
"b"
,
"x"
,
min_rows
=
10
,
nlevels
=
3
)[
"x"
])
==
18
import
pytest
pytest
.
raises
(
PatsyError
,
demo_data
,
"a"
,
"b"
,
"__123"
)
pytest
.
raises
(
TypeError
,
demo_data
,
"a"
,
"b"
,
asdfasdf
=
123
)
class
LookupFactor
(
object
):
"""A simple factor class that simply looks up a named entry in the given
data.
Useful for programatically constructing formulas, and as a simple example
of the factor protocol. For details see
:ref:`expert-model-specification`.
Example::
dmatrix(ModelDesc([], [Term([LookupFactor("x")])]), {"x": [1, 2, 3]})
:arg varname: The name of this variable; used as a lookup key in the
passed in data dictionary/DataFrame/whatever.
:arg force_categorical: If True, then treat this factor as
categorical. (Equivalent to using :func:`C` in a regular formula, but
of course you can't do that with a :class:`LookupFactor`.
:arg contrast: If given, the contrast to use; see :func:`C`. (Requires
``force_categorical=True``.)
:arg levels: If given, the categorical levels; see :func:`C`. (Requires
``force_categorical=True``.)
:arg origin: Either ``None``, or the :class:`Origin` of this factor for use
in error reporting.
.. versionadded:: 0.2.0
The ``force_categorical`` and related arguments.
"""
def
__init__
(
self
,
varname
,
force_categorical
=
False
,
contrast
=
None
,
levels
=
None
,
origin
=
None
):
self
.
_varname
=
varname
self
.
_force_categorical
=
force_categorical
self
.
_contrast
=
contrast
self
.
_levels
=
levels
self
.
origin
=
origin
if
not
self
.
_force_categorical
:
if
contrast
is
not
None
:
raise
ValueError
(
"contrast= requires force_categorical=True"
)
if
levels
is
not
None
:
raise
ValueError
(
"levels= requires force_categorical=True"
)
def
name
(
self
):
return
self
.
_varname
def
__repr__
(
self
):
return
"%s(%r)"
%
(
self
.
__class__
.
__name__
,
self
.
_varname
)
def
__eq__
(
self
,
other
):
return
(
isinstance
(
other
,
LookupFactor
)
and
self
.
_varname
==
other
.
_varname
and
self
.
_force_categorical
==
other
.
_force_categorical
and
self
.
_contrast
==
other
.
_contrast
and
self
.
_levels
==
other
.
_levels
)
def
__ne__
(
self
,
other
):
return
not
self
==
other
def
__hash__
(
self
):
return
hash
((
LookupFactor
,
self
.
_varname
,
self
.
_force_categorical
,
self
.
_contrast
,
self
.
_levels
))
def
memorize_passes_needed
(
self
,
state
,
eval_env
):
return
0
def
memorize_chunk
(
self
,
state
,
which_pass
,
data
):
# pragma: no cover
assert
False
def
memorize_finish
(
self
,
state
,
which_pass
):
# pragma: no cover
assert
False
def
eval
(
self
,
memorize_state
,
data
):
value
=
data
[
self
.
_varname
]
if
self
.
_force_categorical
:
value
=
C
(
value
,
contrast
=
self
.
_contrast
,
levels
=
self
.
_levels
)
return
value
__getstate__
=
no_pickling
def
test_LookupFactor
():
l_a
=
LookupFactor
(
"a"
)
assert
l_a
.
name
()
==
"a"
assert
l_a
==
LookupFactor
(
"a"
)
assert
l_a
!=
LookupFactor
(
"b"
)
assert
hash
(
l_a
)
==
hash
(
LookupFactor
(
"a"
))
assert
hash
(
l_a
)
!=
hash
(
LookupFactor
(
"b"
))
assert
l_a
.
eval
({}, {
"a"
:
1
})
==
1
assert
l_a
.
eval
({}, {
"a"
:
2
})
==
2
assert
repr
(
l_a
)
==
"LookupFactor('a')"
assert
l_a
.
origin
is
None
l_with_origin
=
LookupFactor
(
"b"
,
origin
=
"asdf"
)
assert
l_with_origin
.
origin
==
"asdf"
l_c
=
LookupFactor
(
"c"
,
force_categorical
=
True
,
contrast
=
"CONTRAST"
,
levels
=
(
1
,
2
))
box
=
l_c
.
eval
({}, {
"c"
: [
1
,
1
,
2
]})
assert
box
.
data
==
[
1
,
1
,
2
]
assert
box
.
contrast
==
"CONTRAST"
assert
box
.
levels
==
(
1
,
2
)
import
pytest
pytest
.
raises
(
ValueError
,
LookupFactor
,
"nc"
,
contrast
=
"CONTRAST"
)
pytest
.
raises
(
ValueError
,
LookupFactor
,
"nc"
,
levels
=
(
1
,
2
))
assert_no_pickling
(
LookupFactor
(
"a"
))
Back
|
FazBrowse Home
|
New Git URL