Skip to content

Commit f95df29

Browse files
committed
implement empty_like, zeros_like, etc.
1 parent db9241f commit f95df29

File tree

4 files changed

+268
-2
lines changed

4 files changed

+268
-2
lines changed

zarr/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from __future__ import absolute_import, print_function, division
33

44

5-
from zarr.core import empty, zeros, ones, full, array, open
5+
from zarr.create import empty, zeros, ones, full, array, open, empty_like, \
6+
zeros_like, ones_like, full_like, open_like
67
from zarr.ext import blosc_version
78
from zarr import defaults
89
from zarr import constants

zarr/core.py renamed to zarr/create.py

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def array(data, chunks=None, dtype=None, cname=None, clevel=None,
287287

288288
# noinspection PyShadowingBuiltins
289289
def open(path, mode='a', shape=None, chunks=None, dtype=None, cname=None,
290-
clevel=None, shuffle=None, fill_value=None, synchronized=True,
290+
clevel=None, shuffle=None, fill_value=0, synchronized=True,
291291
lazy=False):
292292
"""Open a persistent array.
293293
@@ -343,3 +343,94 @@ def open(path, mode='a', shape=None, chunks=None, dtype=None, cname=None,
343343
return cls(path=path, mode=mode, shape=shape, chunks=chunks, dtype=dtype,
344344
cname=cname, clevel=clevel, shuffle=shuffle,
345345
fill_value=fill_value)
346+
347+
348+
def empty_like(z, shape=None, chunks=None, dtype=None, cname=None, clevel=None,
349+
shuffle=None, synchronized=None, lazy=None):
350+
"""Create an empty array like 'z'."""
351+
352+
shape = shape if shape is not None else z.shape
353+
chunks = chunks if chunks is not None else z.chunks
354+
dtype = dtype if dtype is not None else z.dtype
355+
cname = cname if cname is not None else z.cname
356+
clevel = clevel if clevel is not None else z.clevel
357+
shuffle = shuffle if shuffle is not None else z.shuffle
358+
synchronized = synchronized if synchronized is not None \
359+
else z.is_synchronized
360+
lazy = lazy if lazy is not None else z.is_lazy
361+
return empty(shape, chunks, dtype=dtype, cname=cname, clevel=clevel,
362+
shuffle=shuffle, synchronized=synchronized, lazy=lazy)
363+
364+
365+
def zeros_like(z, shape=None, chunks=None, dtype=None, cname=None, clevel=None,
366+
shuffle=None, synchronized=None, lazy=None):
367+
"""Create an array of zeros like 'z'."""
368+
369+
shape = shape if shape is not None else z.shape
370+
chunks = chunks if chunks is not None else z.chunks
371+
dtype = dtype if dtype is not None else z.dtype
372+
cname = cname if cname is not None else z.cname
373+
clevel = clevel if clevel is not None else z.clevel
374+
shuffle = shuffle if shuffle is not None else z.shuffle
375+
synchronized = synchronized if synchronized is not None \
376+
else z.is_synchronized
377+
lazy = lazy if lazy is not None else z.is_lazy
378+
return zeros(shape, chunks, dtype=dtype, cname=cname, clevel=clevel,
379+
shuffle=shuffle, synchronized=synchronized, lazy=lazy)
380+
381+
382+
def ones_like(z, shape=None, chunks=None, dtype=None, cname=None, clevel=None,
383+
shuffle=None, synchronized=None, lazy=None):
384+
"""Create an array of ones like 'z'."""
385+
386+
shape = shape if shape is not None else z.shape
387+
chunks = chunks if chunks is not None else z.chunks
388+
dtype = dtype if dtype is not None else z.dtype
389+
cname = cname if cname is not None else z.cname
390+
clevel = clevel if clevel is not None else z.clevel
391+
shuffle = shuffle if shuffle is not None else z.shuffle
392+
synchronized = synchronized if synchronized is not None \
393+
else z.is_synchronized
394+
lazy = lazy if lazy is not None else z.is_lazy
395+
return ones(shape, chunks, dtype=dtype, cname=cname, clevel=clevel,
396+
shuffle=shuffle, synchronized=synchronized, lazy=lazy)
397+
398+
399+
def full_like(z, shape=None, chunks=None, fill_value=None, dtype=None,
400+
cname=None, clevel=None, shuffle=None, synchronized=None,
401+
lazy=None):
402+
"""Create a filled array like 'z'."""
403+
404+
shape = shape if shape is not None else z.shape
405+
chunks = chunks if chunks is not None else z.chunks
406+
dtype = dtype if dtype is not None else z.dtype
407+
cname = cname if cname is not None else z.cname
408+
clevel = clevel if clevel is not None else z.clevel
409+
shuffle = shuffle if shuffle is not None else z.shuffle
410+
fill_value = fill_value if fill_value is not None else z.fill_value
411+
synchronized = synchronized if synchronized is not None \
412+
else z.is_synchronized
413+
lazy = lazy if lazy is not None else z.is_lazy
414+
return full(shape, chunks, fill_value, dtype=dtype, cname=cname,
415+
clevel=clevel, shuffle=shuffle, synchronized=synchronized,
416+
lazy=lazy)
417+
418+
419+
def open_like(z, path, mode='a', shape=None, chunks=None, dtype=None,
420+
cname=None, clevel=None, shuffle=None, fill_value=None,
421+
synchronized=None, lazy=None):
422+
"""Open a persistent array like 'z'."""
423+
424+
shape = shape if shape is not None else z.shape
425+
chunks = chunks if chunks is not None else z.chunks
426+
dtype = dtype if dtype is not None else z.dtype
427+
cname = cname if cname is not None else z.cname
428+
clevel = clevel if clevel is not None else z.clevel
429+
shuffle = shuffle if shuffle is not None else z.shuffle
430+
fill_value = fill_value if fill_value is not None else z.fill_value
431+
synchronized = synchronized if synchronized is not None \
432+
else z.is_synchronized
433+
lazy = lazy if lazy is not None else z.is_lazy
434+
return open(path, mode=mode, shape=shape, chunks=chunks, dtype=dtype,
435+
cname=cname, clevel=clevel, shuffle=shuffle,
436+
fill_value=fill_value, synchronized=synchronized, lazy=lazy)

zarr/ext.pyx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,10 @@ cdef class BaseArray:
801801
def __get__(self):
802802
return self._shuffle
803803

804+
property fill_value:
805+
def __get__(self):
806+
return self._fill_value
807+
804808
# derived properties
805809

806810
property size:
@@ -823,6 +827,18 @@ cdef class BaseArray:
823827
def __get__(self):
824828
return self.chunk_size * self.itemsize
825829

830+
property is_synchronized:
831+
def __get__(self):
832+
return False
833+
834+
property is_lazy:
835+
def __get__(self):
836+
return False
837+
838+
property is_persistent:
839+
def __get__(self):
840+
return False
841+
826842
def __getitem__(self, item):
827843
cdef ndarray dest
828844
cdef BaseChunk chunk
@@ -1132,6 +1148,10 @@ cdef class SynchronizedArray(Array):
11321148
shuffle=self._shuffle,
11331149
fill_value=self._fill_value)
11341150

1151+
property is_synchronized:
1152+
def __get__(self):
1153+
return True
1154+
11351155

11361156
# noinspection PyAttributeOutsideInit
11371157
cdef class PersistentArray(BaseArray):
@@ -1254,6 +1274,10 @@ cdef class PersistentArray(BaseArray):
12541274
a.flat = [c.is_initialized for c in self._cdata.flat]
12551275
return a
12561276

1277+
property is_persistent:
1278+
def __get__(self):
1279+
return True
1280+
12571281
cdef BaseChunk get_chunk(self, tuple cidx):
12581282
return self._cdata[cidx]
12591283

@@ -1316,6 +1340,10 @@ cdef class SynchronizedPersistentArray(PersistentArray):
13161340
shuffle=self._shuffle, fill_value=self._fill_value
13171341
)
13181342

1343+
property is_synchronized:
1344+
def __get__(self):
1345+
return True
1346+
13191347

13201348
###############################################################################
13211349
# LAZY ARRAY CLASSES #
@@ -1410,6 +1438,10 @@ cdef class LazyArray(BaseArray):
14101438
a[cidx] = chunk.is_initialized
14111439
return a
14121440

1441+
property is_lazy:
1442+
def __get__(self):
1443+
return True
1444+
14131445
cdef BaseChunk create_chunk(self, tuple cidx):
14141446
# ignore chunk index here, not needed
14151447
return Chunk(shape=self._chunks, dtype=self._dtype, cname=self._cname,
@@ -1449,6 +1481,10 @@ cdef class SynchronizedLazyArray(LazyArray):
14491481
shuffle=self._shuffle,
14501482
fill_value=self._fill_value)
14511483

1484+
property is_synchronized:
1485+
def __get__(self):
1486+
return True
1487+
14521488

14531489
# noinspection PyAbstractClass,PyAttributeOutsideInit
14541490
cdef class LazyPersistentArray(PersistentArray):
@@ -1480,6 +1516,10 @@ cdef class LazyPersistentArray(PersistentArray):
14801516
a[cidx] = True
14811517
return a
14821518

1519+
property is_lazy:
1520+
def __get__(self):
1521+
return True
1522+
14831523
cdef BaseChunk get_chunk(self, tuple cidx):
14841524
return _lazy_get_chunk(self, cidx)
14851525

@@ -1547,3 +1587,7 @@ cdef class SynchronizedLazyPersistentArray(LazyPersistentArray):
15471587
cname=self._cname, clevel=self._clevel, shuffle=self._shuffle,
15481588
fill_value=self._fill_value
15491589
)
1590+
1591+
property is_synchronized:
1592+
def __get__(self):
1593+
return True

zarr/tests/test_create.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import absolute_import, print_function, division
3+
4+
5+
import tempfile
6+
import shutil
7+
import atexit
8+
import os
9+
import numpy as np
10+
from nose.tools import eq_ as eq
11+
from numpy.testing import assert_array_equal
12+
13+
14+
from zarr import array, empty, zeros, ones, full, open, empty_like, \
15+
zeros_like, ones_like, full_like, open_like
16+
17+
18+
def test_array():
19+
a = np.arange(100)
20+
z = array(a, chunks=10)
21+
eq(a.shape, z.shape)
22+
eq(a.dtype, z.dtype)
23+
assert_array_equal(a, z[:])
24+
25+
26+
def test_empty():
27+
z = empty(100, 10)
28+
eq((100,), z.shape)
29+
eq((10,), z.chunks)
30+
31+
32+
def test_zeros():
33+
z = zeros(100, 10)
34+
eq((100,), z.shape)
35+
eq((10,), z.chunks)
36+
assert_array_equal(np.zeros(100), z[:])
37+
38+
39+
def test_ones():
40+
z = ones(100, 10)
41+
eq((100,), z.shape)
42+
eq((10,), z.chunks)
43+
assert_array_equal(np.ones(100), z[:])
44+
45+
46+
def test_full():
47+
z = full(100, 10, fill_value=42, dtype='i4')
48+
eq((100,), z.shape)
49+
eq((10,), z.chunks)
50+
assert_array_equal(np.full(100, fill_value=42, dtype='i4'), z[:])
51+
52+
53+
def test_open():
54+
path = tempfile.mktemp()
55+
atexit.register(
56+
lambda: shutil.rmtree(path) if os.path.exists(path) else None
57+
)
58+
z = open(path, mode='w', shape=100, chunks=10, dtype='i4')
59+
z[:] = 42
60+
eq((100,), z.shape)
61+
eq((10,), z.chunks)
62+
assert_array_equal(np.full(100, fill_value=42, dtype='i4'), z[:])
63+
z2 = open(path, mode='r')
64+
eq((100,), z2.shape)
65+
eq((10,), z2.chunks)
66+
assert_array_equal(z[:], z2[:])
67+
68+
69+
def test_empty_like():
70+
z = empty(100, 10)
71+
z2 = empty_like(z)
72+
eq(z.shape, z2.shape)
73+
eq(z.chunks, z2.chunks)
74+
eq(z.dtype, z2.dtype)
75+
eq(z.cname, z2.cname)
76+
eq(z.clevel, z2.clevel)
77+
eq(z.shuffle, z2.shuffle)
78+
eq(z.fill_value, z2.fill_value)
79+
80+
81+
def test_zeros_like():
82+
z = zeros(100, 10)
83+
z2 = zeros_like(z)
84+
eq(z.shape, z2.shape)
85+
eq(z.chunks, z2.chunks)
86+
eq(z.dtype, z2.dtype)
87+
eq(z.cname, z2.cname)
88+
eq(z.clevel, z2.clevel)
89+
eq(z.shuffle, z2.shuffle)
90+
eq(z.fill_value, z2.fill_value)
91+
92+
93+
def test_ones_like():
94+
z = ones(100, 10)
95+
z2 = ones_like(z)
96+
eq(z.shape, z2.shape)
97+
eq(z.chunks, z2.chunks)
98+
eq(z.dtype, z2.dtype)
99+
eq(z.cname, z2.cname)
100+
eq(z.clevel, z2.clevel)
101+
eq(z.shuffle, z2.shuffle)
102+
eq(z.fill_value, z2.fill_value)
103+
104+
105+
def test_full_like():
106+
z = full(100, 10, fill_value=42)
107+
z2 = full_like(z)
108+
eq(z.shape, z2.shape)
109+
eq(z.chunks, z2.chunks)
110+
eq(z.dtype, z2.dtype)
111+
eq(z.cname, z2.cname)
112+
eq(z.clevel, z2.clevel)
113+
eq(z.shuffle, z2.shuffle)
114+
eq(z.fill_value, z2.fill_value)
115+
116+
117+
def test_open_like():
118+
path = tempfile.mktemp()
119+
atexit.register(
120+
lambda: shutil.rmtree(path) if os.path.exists(path) else None
121+
)
122+
z = full(100, 10, fill_value=42)
123+
z2 = open_like(z, path)
124+
eq(z.shape, z2.shape)
125+
eq(z.chunks, z2.chunks)
126+
eq(z.dtype, z2.dtype)
127+
eq(z.cname, z2.cname)
128+
eq(z.clevel, z2.clevel)
129+
eq(z.shuffle, z2.shuffle)
130+
eq(z.fill_value, z2.fill_value)

0 commit comments

Comments
 (0)