Browse files

ENH Code and test mods for Python 3.

  • Loading branch information...
1 parent 15f34cf commit 63665b7c58f7e2940888dee02735f89737f501ae jmcloughlin committed Nov 5, 2012
Showing with 203 additions and 122 deletions.
  1. +2 −2 README.rst
  2. +146 −10 la/deflarry.py
  3. +1 −1 la/flarry.py
  4. +19 −9 la/io.py
  5. +8 −65 la/tests/deflarry_test.py
  6. +5 −4 la/tests/empty_larry_test.py
  7. +17 −17 la/tests/flarry_test.py
  8. +5 −14 la/tests/more_test.py
View
4 README.rst
@@ -122,9 +122,9 @@ After you have installed ``la``, run the suite of unit tests::
>>> import la
>>> la.test()
<snip>
- Ran 3020 tests in 9.225s
+ Ran 3012 tests in 9.225s
OK
- <nose.result.TextTestResult run=3020 errors=0 failures=0>
+ <nose.result.TextTestResult run=3012 errors=0 failures=0>
The ``la`` package contains C extensions that speed up common alignment
operations such as adding two unaligned larrys. If the C extensions don't
View
156 la/deflarry.py
@@ -631,7 +631,7 @@ def invert(self):
array([False, True], dtype=bool)
"""
- if self.dtype is not bool:
+ if self.dtype.type is not np.bool_:
raise TypeError('Only larrys with bool dtype can be inverted.')
return larry(~self.x, self.copylabel(), validate=False)
@@ -791,6 +791,120 @@ def __rdiv__(self, other):
x = other / self.x
return larry(x, label, validate=False)
raise TypeError('Input must be scalar, array, or larry.')
+
+ def __truediv__(self, other):
+ """
+ True divide a larry with another larry, Numpy array, or scalar.
+
+ If two larrys are divided then the larrys are joined with an inner
+ join (i.e., the intersection of the labels).
+
+ See Also
+ --------
+ la.divide: divide two larrys element-wise using given join method.
+
+ Examples
+ --------
+
+ >>> larry([1.0, 2.0]) / larry([2.0, 3.0])
+ label_0
+ 0
+ 1
+ x
+ array([ 0.5 , 0.66666667])
+
+ >>> y1 = larry([1,2], [['a', 'b']])
+ >>> y2 = larry([1,2], [['b', 'c']])
+ >>> y1 / y2
+ label_0
+ b
+ x
+ array([2.])
+
+ """
+ if isinstance(other, larry):
+ if self.label == other.label:
+ x = self.x / other.x
+ label = self.copylabel()
+ return larry(x, label, validate=False)
+ else:
+ x, y, label = self.__align(other)
+ x = x / y
+ return larry(x, label, validate=False)
+ if np.isscalar(other) or isinstance(other, np.ndarray):
+ x = self.x / other
+ label = self.copylabel()
+ return larry(x, label, validate=False)
+ raise TypeError('Input must be scalar, array, or larry.')
+
+ def __floordiv__(self, other):
+ """
+ Floor divide a larry with another larry, Numpy array, or scalar.
+
+ If two larrys are divided then the larrys are joined with an inner
+ join (i.e., the intersection of the labels).
+
+ See Also
+ --------
+ la.divide: divide two larrys element-wise using given join method.
+
+ Examples
+ --------
+
+ >>> larry([1.0, 2.0]) // larry([2.0, 3.0])
+ label_0
+ 0
+ 1
+ x
+ array([ 0., 0.])
+
+ >>> y1 = larry([1,2], [['a', 'b']])
+ >>> y2 = larry([1,2], [['b', 'c']])
+ >>> y1 // y2
+ label_0
+ b
+ x
+ array([2])
+
+ """
+ if isinstance(other, larry):
+ if self.label == other.label:
+ x = self.x // other.x
+ label = self.copylabel()
+ return larry(x, label, validate=False)
+ else:
+ x, y, label = self.__align(other)
+ x = x // y
+ return larry(x, label, validate=False)
+ if np.isscalar(other) or isinstance(other, np.ndarray):
+ x = self.x // other
+ label = self.copylabel()
+ return larry(x, label, validate=False)
+ raise TypeError('Input must be scalar, array, or larry.')
+
+ def __rtruediv__(self, other):
+ "Right true divide a larry with a another larry, Numpy array, or scalar."
+ if isinstance(other, larry):
+ msg = 'I could not come up with a problem that used this code '
+ msg += 'so I removed it. Send me your example and I will fix.'
+ raise RuntimeError(msg)
+ if np.isscalar(other) or isinstance(other, np.ndarray):
+ label = self.copylabel()
+ x = other / self.x
+ return larry(x, label, validate=False)
+ raise TypeError('Input must be scalar, array, or larry.')
+
+ def __rfloordiv__(self, other):
+ "Right floor divide a larry with a another larry, Numpy array, or scalar."
+ if isinstance(other, larry):
+ msg = 'I could not come up with a problem that used this code '
+ msg += 'so I removed it. Send me your example and I will fix.'
+ raise RuntimeError(msg)
+ if np.isscalar(other) or isinstance(other, np.ndarray):
+ label = self.copylabel()
+ x = other // self.x
+ return larry(x, label, validate=False)
+ raise TypeError('Input must be scalar, array, or larry.')
def __mul__(self, other):
"""
@@ -2326,10 +2440,32 @@ def keep_label(self, op, value, axis):
raise ValueError('axis cannot be None')
if axis >= self.ndim:
raise IndexError('axis is out of range')
- y = self.copy()
- cmd = '[(idx, z) for idx, z in enumerate(y.label[axis]) if z '
- cmd = cmd + op + ' value]'
- idxlabel = eval(cmd)
+ y = self.copy()
+
+ if op == '==':
+ idxlabel = [(idx, z) for idx, z in enumerate(y.label[axis])
+ if z == value]
+ elif op == '>':
+ idxlabel = [(idx, z) for idx, z in enumerate(y.label[axis])
+ if z > value]
+ elif op == '<':
+ idxlabel = [(idx, z) for idx, z in enumerate(y.label[axis])
+ if z < value]
+ elif op == '>=':
+ idxlabel = [(idx, z) for idx, z in enumerate(y.label[axis])
+ if z >= value]
+ elif op == '<=':
+ idxlabel = [(idx, z) for idx, z in enumerate(y.label[axis])
+ if z <= value]
+ elif op == '!=':
+ idxlabel = [(idx, z) for idx, z in enumerate(y.label[axis])
+ if z != value]
+ elif op == 'in':
+ idxlabel = [(idx, z) for idx, z in enumerate(y.label[axis])
+ if z in value]
+ elif op == 'not in':
+ idxlabel = [(idx, z) for idx, z in enumerate(y.label[axis])
+ if z not in value]
if len(idxlabel) == 0:
return larry([])
else:
@@ -2486,10 +2622,10 @@ def labelindex(self, name, axis, exact=True):
1
"""
+ if axis is None:
+ raise ValueError('axis cannot be None')
if axis >= self.ndim:
raise IndexError('axis out of range')
- if axis is None:
- raise ValueError('axis cannot be None')
try:
index = self.label[axis].index(name)
except ValueError:
@@ -3351,15 +3487,15 @@ def merge(self, other, update=False):
dtype1 = self.dtype
if dtype1 == object:
mask1 = lar1.x != [None]
- elif self.dtype.type == np.string_:
+ elif self.dtype.type == np.str_:
mask1 = lar1.x != ''
else:
mask1 = np.isfinite(lar1.x)
dtype2 = other.dtype
if dtype2 == object:
mask2 = lar2.x != [None]
- elif self.dtype.type == np.string_:
- mask2 = lar2.x != ''
+ elif self.dtype.type == np.str_:
+ mask2 = lar2.x != ''
else:
mask2 = np.isfinite(lar2.x)
View
2 la/flarry.py
@@ -295,7 +295,7 @@ def align_raw(lar1, lar2, join='inner', cast=True):
elif joinax == 'outer':
if list1 == list2:
list3 = list(list1)
- else:
+ else:
list3 = list(set(list1).union(list2))
list3.sort()
idx1, idx1_miss = listmap_fill(list1, list3, fill=0)
View
28 la/io.py
@@ -2,6 +2,7 @@
import os
import datetime
+import sys
import numpy as np
import h5py
@@ -226,7 +227,7 @@ def __repr__(self):
# but I don't want to load the array, I just want the shape
shape = str(self.f[key]['x'].shape)
dtype = str(self.f[key]['x'].dtype)
- table.append([key, dtype, shape])
+ table.append([key, dtype, shape])
return indent(table, hasHeader=True, delim=' ')
@property
@@ -321,15 +322,24 @@ def __init__(self, group):
self.x = group['x']
self.label = _load_label(group, len(self.x.shape))
- # Grab these methods from larry
- __getitem__ = larry.__getitem__.im_func
- __setitem__ = larry.__setitem__.im_func
- maxlabel = larry.maxlabel.im_func
- minlabel = larry.minlabel.im_func
- getlabel = larry.getlabel.im_func
- labelindex = larry.labelindex.im_func
+ # Grab these methods from larry
+ if sys.version_info[0] < 3:
+ __getitem__ = larry.__getitem__.im_func
+ __setitem__ = larry.__setitem__.im_func
+ maxlabel = larry.maxlabel.im_func
+ minlabel = larry.minlabel.im_func
+ getlabel = larry.getlabel.im_func
+ labelindex = larry.labelindex.im_func
+ else:
+ __getitem__ = larry.__getitem__
+ __setitem__ = larry.__setitem__
+ maxlabel = larry.maxlabel
+ minlabel = larry.minlabel
+ getlabel = larry.getlabel
+ labelindex = larry.labelindex
+
shape = larry.shape
- dtype = larry.dtype
+ dtype = larry.dtype
@property
def ndim(self):
View
73 la/tests/deflarry_test.py
@@ -1259,21 +1259,7 @@ def test_lt_3(self):
def test_lt_4(self):
"larry.__lt___4"
date = datetime.date(2004, 1, 1)
- self.assertRaises(TypeError, self.l.__lt__, date)
-
- def test_lt_5(self):
- "larry.__lt___5"
- lar = la.larry([1, 2, 3])
- actual = lar < 'a'
- desired = lar.x < 'a'
- self.assertTrue(actual == desired, "failed")
-
- def test_lt_6(self):
- "larry.__lt___6"
- lar = la.larry(['a', 'b', 'c'])
- actual = lar < 1
- desired = lar.x < 1
- self.assertTrue(actual == desired, "failed")
+ self.assertRaises(TypeError, self.l.__lt__, date)
def test_gt_1(self):
"larry.__gt___1"
@@ -1312,20 +1298,6 @@ def test_gt_4(self):
"larry.__gt___4"
date = datetime.date(2004, 1, 1)
self.assertRaises(TypeError, self.l.__gt__, date)
-
- def test_gt_5(self):
- "larry.__gt___5"
- lar = la.larry([1, 2, 3])
- actual = lar > 'a'
- desired = lar.x > 'a'
- self.assertTrue(actual == desired, "failed")
-
- def test_gt_6(self):
- "larry.__gt___6"
- lar = la.larry(['a', 'b', 'c'])
- actual = lar > 1
- desired = lar.x > 1
- self.assertTrue(actual == desired, "failed")
def test_le_1(self):
"larry.__le___1"
@@ -1363,21 +1335,7 @@ def test_le_3(self):
def test_le_4(self):
"larry.__le___4"
date = datetime.date(2004, 1, 1)
- self.assertRaises(TypeError, self.l.__le__, date)
-
- def test_le_5(self):
- "larry.__le___5"
- lar = la.larry([1, 2, 3])
- actual = lar <= 'a'
- desired = lar.x <= 'a'
- self.assertTrue(actual == desired, "failed")
-
- def test_le_6(self):
- "larry.__le___6"
- lar = la.larry(['a', 'b', 'c'])
- actual = lar <= 1
- desired = lar.x <= 1
- self.assertTrue(actual == desired, "failed")
+ self.assertRaises(TypeError, self.l.__le__, date)
def test_ge_1(self):
"larry.__ge___1"
@@ -1411,21 +1369,6 @@ def test_ge_3(self):
self.assertTrue((t == p.x).all(), msg)
label = [[0, 1, 2], [0, 1]]
self.assertTrue(label == p.label, printfail(label, p.label, 'label'))
-
- def test_ge_4(self):
- "larry.__ge___4"
- lar = la.larry([1, 2, 3])
- actual = lar >= 'a'
- desired = lar.x >= 'a'
- self.assertTrue(actual == desired, "failed")
-
- def test_ge_5(self):
- "larry.__ge___5"
- lar = la.larry(['a', 'b', 'c'])
- actual = lar >= 1
- desired = lar.x >= 1
- self.assertTrue(actual == desired, "failed")
-
class Test_anyall(unittest.TestCase):
"Test any and all of the larry class"
@@ -3272,12 +3215,12 @@ def test_merge1(self):
np.array([[ 2., 2., 3., 1.],
[ 3., 2., 2., 1.],
[ 1., 1., 1., 1.]]),
- [[1, 2, 3], ['A', 2, 3, 4]])
+ [[1, 2, 3], [9, 2, 3, 4]])
larr = larry(
np.array([[ 2., 2., 3., 1., 2.],
[ 3., 2., 2., 1., 3.],
[ 1., 1., 1., 1., 1.]]),
- [[1, 2, 3], [1, 2, 3, 4, 'A']])
+ [[1, 2, 3], [1, 2, 3, 4, 9]])
larm = lar1.merge(lar2, update=True)
assert_almost_equal(larr.x, larm.x)
assert_(larr.label == larm.label)
@@ -3294,12 +3237,12 @@ def test_merge2(self):
np.array([[ 2., nan, 3., 1.],
[ 3., nan, 2., 1.],
[ 1., nan, 1., 6.]]),
- [[1, 2, 3], ['A', 2, 3, 4]])
+ [[1, 2, 3], [9, 2, 3, 4]])
larr = larry(
np.array([[ 2., 2., 3., 1., 2.],
[ 3., 2., 2., 1., 3.],
[ 1., 1., 1., 6., 1.]]),
- [[1, 2, 3], [1, 2, 3, 4, 'A']])
+ [[1, 2, 3], [1, 2, 3, 4, 9]])
larm = lar1.merge(lar2, update=False)
assert_almost_equal(larr.x, larm.x)
assert_(larr.label == larm.label)
@@ -3315,12 +3258,12 @@ def test_merge3(self):
np.array([[ 2., nan, 3., 1.],
[ 3., nan, 2., 1.],
[ 1., nan, 1., 6.]]),
- [[1, 2, 3], ['A', 2, 3, 4]])
+ [[1, 2, 3], [9, 2, 3, 4]])
larr = larry(
np.array([[ 2., 2., 3., 1., 2.],
[ 3., 2., 2., 1., 3.],
[ nan, nan, 1., 6., 1.]]),
- [[1, 2, 3], [1, 2, 3, 4, 'A']])
+ [[1, 2, 3], [1, 2, 3, 4, 9]])
larm = lar1.merge(lar2, update=True)
assert_almost_equal(larr.x, larm.x)
assert_(larr.label == larm.label)
View
9 la/tests/empty_larry_test.py
@@ -156,8 +156,8 @@ def test_empty():
# Check that the right shape and value are returned by the reducing methods
# when the input has a shape tuple that contains 0
-#False = np.False_
-#True = ~False
+FALSE = np.False_
+TRUE = ~FALSE
def reduce_methods():
r = [{'la': 'sum', 'np': 'sum', 'dflt': nan, 'kw': {}},
@@ -169,8 +169,8 @@ def reduce_methods():
{'la': 'min', 'np': 'sum', 'dflt': nan, 'kw': {}},
{'la': 'std', 'np': 'sum', 'dflt': nan, 'kw': {}},
{'la': 'var', 'np': 'sum', 'dflt': nan, 'kw': {}},
- {'la': 'any', 'np': 'sum', 'dflt': False, 'kw': {}},
- {'la': 'all', 'np': 'sum', 'dflt': True, 'kw': {}},
+ {'la': 'any', 'np': 'sum', 'dflt': FALSE, 'kw': {}},
+ {'la': 'all', 'np': 'sum', 'dflt': TRUE, 'kw': {}},
{'la': 'lastrank', 'np': 'sum', 'dflt': nan, 'kw': {}},
{'la': 'lastrank', 'np': 'sum', 'dflt': nan, 'kw': {'decay': 10}}]
return r
@@ -200,6 +200,7 @@ def test_reduce_shape():
ymethod = getattr(y, method['la'])
lar = ymethod(axis=axis, **method['kw'])
yield ale, lar, arr, msg % (method['la'], shape, axis)
+
def test_50():
"Regression #50"
actual = larry([], dtype=np.int).sum(0)
View
34 la/tests/flarry_test.py
@@ -171,9 +171,9 @@ def test_unique_2(self):
def test_unique_3(self):
lar = larry(['a', 'b', 'b', 'c', 'a'])
u, indices = unique(lar, return_index=True)
- assert_array_equal(u, np.array(['a', 'b', 'c'], dtype='|S1'))
+ assert_array_equal(u, np.array(['a', 'b', 'c']))
assert_array_equal(indices, np.array([0, 1, 3]))
- assert_array_equal(lar[indices], np.array(['a','b','c'], dtype='|S1'))
+ assert_array_equal(lar[indices], np.array(['a','b','c']))
def test_unique_4(self):
lar = larry([1, 2, 6, 4, 2, 3, 2])
@@ -304,10 +304,10 @@ def test_1d11(self):
def test_1d12(self):
"align 1d test #12"
y1 = larry([1, 2])
- y2 = larry([1, 2], [['a', 'b']])
+ y2 = larry([1, 2], [[3, 4]])
a1, a2 = align(y1, y2, join='outer')
- d1 = larry([1, 2, nan, nan], [[0, 1, 'a', 'b']], dtype=float)
- d2 = larry([nan, nan, 1, 2], [[0, 1, 'a', 'b']], dtype=float)
+ d1 = larry([1, 2, nan, nan], [[0, 1, 3, 4]], dtype=float)
+ d2 = larry([nan, nan, 1, 2], [[0, 1, 3, 4]], dtype=float)
msg = "align 1d fail on %s larry"
ale(a1, d1, msg % 'left', original=y1)
ale(a2, d2, msg % 'right', original=y2)
@@ -906,29 +906,29 @@ def test_binaryop_17(self):
def test_binaryop_18(self):
"binaryop test #18"
y1 = larry([1, nan, nan, 1])
- y2 = larry([1, 1, nan, 1], [[0, 1, 2, 'a']])
+ y2 = larry([1, 1, nan, 1], [[0, 1, 2, 9]])
actual = binaryop(np.add, y1, y2, join='outer')
- desired = larry([2, nan, nan, nan, nan], [[0, 1, 2, 3, 'a']])
+ desired = larry([2, nan, nan, nan, nan], [[0, 1, 2, 3, 9]])
msg = "binaryop failed"
ale(actual, desired, msg, original=y1)
ale(actual, desired, msg, original=y2)
def test_binaryop_19(self):
"binaryop test #19"
y1 = larry([1, nan, nan, 1])
- y2 = larry([1, 1, nan, 1], [[0, 1, 2, 'a']])
+ y2 = larry([1, 1, nan, 1], [[0, 1, 2, 9]])
actual = binaryop(np.add, y1, y2, join='outer', missone=0)
- desired = larry([2, 1, nan, 1, 1], [[0, 1, 2, 3, 'a']])
+ desired = larry([2, 1, nan, 1, 1], [[0, 1, 2, 3, 9]])
msg = "binaryop failed"
ale(actual, desired, msg, original=y1)
ale(actual, desired, msg, original=y2)
def test_binaryop_20(self):
"binaryop test #20"
y1 = larry([1, nan, nan, 1])
- y2 = larry([1, 1, nan, 1], [[0, 1, 2, 'a']])
+ y2 = larry([1, 1, nan, 1], [[0, 1, 2, 9]])
actual = binaryop(np.add, y1, y2, join='outer', missone=0, misstwo=0)
- desired = larry([2, 1, 0, 1, 1], [[0, 1, 2, 3, 'a']], dtype=float)
+ desired = larry([2, 1, 0, 1, 1], [[0, 1, 2, 3, 9]], dtype=float)
msg = "binaryop failed"
ale(actual, desired, msg, original=y1)
ale(actual, desired, msg, original=y2)
@@ -1133,29 +1133,29 @@ def test_add_17(self):
def test_add_18(self):
"add test #18"
y1 = larry([1, nan, nan, 1])
- y2 = larry([1, 1, nan, 1], [[0, 1, 2, 'a']])
+ y2 = larry([1, 1, nan, 1], [[0, 1, 2, 9]])
actual = add(y1, y2, join='outer')
- desired = larry([2, nan, nan, nan, nan], [[0, 1, 2, 3, 'a']])
+ desired = larry([2, nan, nan, nan, nan], [[0, 1, 2, 3, 9]])
msg = "add failed"
ale(actual, desired, msg, original=y1)
ale(actual, desired, msg, original=y2)
def test_add_19(self):
"add test #19"
y1 = larry([1, nan, nan, 1])
- y2 = larry([1, 1, nan, 1], [[0, 1, 2, 'a']])
+ y2 = larry([1, 1, nan, 1], [[0, 1, 2, 9]])
actual = add(y1, y2, join='outer', missone=0)
- desired = larry([2, 1, nan, 1, 1], [[0, 1, 2, 3, 'a']])
+ desired = larry([2, 1, nan, 1, 1], [[0, 1, 2, 3, 9]])
msg = "add failed"
ale(actual, desired, msg, original=y1)
ale(actual, desired, msg, original=y2)
def test_add_20(self):
"add test #20"
y1 = larry([1, nan, nan, 1])
- y2 = larry([1, 1, nan, 1], [[0, 1, 2, 'a']])
+ y2 = larry([1, 1, nan, 1], [[0, 1, 2, 9]])
actual = add(y1, y2, join='outer', missone=0, misstwo=0)
- desired = larry([2, 1, 0, 1, 1], [[0, 1, 2, 3, 'a']], dtype=float)
+ desired = larry([2, 1, 0, 1, 1], [[0, 1, 2, 3, 9]], dtype=float)
msg = "add failed"
ale(actual, desired, msg, original=y1)
ale(actual, desired, msg, original=y2)
View
19 la/tests/more_test.py
@@ -1,4 +1,4 @@
-# these are tests for use with nose using generators, not for unittest.
+"This only tests that functions run and return appropriate types (arrays, scalars)"
# For support of python 2.5
from __future__ import with_statement
@@ -62,17 +62,8 @@ def test_return_array():
args = (xc, sectors)
with np.errstate(invalid='ignore', divide='ignore'):
yield check_return_array, func, args
-
-def check_3d(func, args):
- res = func(*args)
- if type(res) is tuple:
- res1 = res[0]
- else:
- res1 = res
- assert_(np.shape(res1)>0, repr(func)+'does not return array for 3d')
def test_3d():
- # many of these tests fail, skip to reduce noise during testing
x = np.array([[9.0, 3.0, nan, nan, 9.0, nan],
[1.0, 1.0, 1.0, nan, nan, nan],
[2.0, 2.0, 0.1, nan, 1.0, nan], # 0.0 kills geometric mean
@@ -86,22 +77,22 @@ def test_3d():
xc = x.copy()
args = (xc,)
with np.errstate(invalid='ignore', divide='ignore'):
- yield check_3d, func, args
+ yield check_return_array, func, args
for func in funcs_oneint:
xc = x.copy()
args = (xc, 2)
with np.errstate(invalid='ignore', divide='ignore'):
- yield check_3d, func, args
+ yield check_return_array, func, args
for func in funcs_onefrac:
xc = x.copy()
args = (xc, -1, 0.5)
with np.errstate(invalid='ignore', divide='ignore'):
- yield check_3d, func, args
+ yield check_return_array, func, args
for func in funcs_sect:
xc = x.copy()
args = (xc, sectors)
with np.errstate(invalid='ignore', divide='ignore'):
- yield check_3d, func, args
+ yield check_return_array, func, args

0 comments on commit 63665b7

Please sign in to comment.