2012-05-03 8 views
2

python pickleファイルに書き込むときにnumpyに非標準ストライドを保持するよう指示する方法はありますか?python pickleファイルのnumpyストライドの保持

>>> # Create an array with non-standard striding 
>>> x = numpy.arange(2*3*4, dtype='uint8').reshape((2,3,4)).transpose(0,2,1) 

>>> x.strides 
(12, 1, 4) 

>>> # The pickling process converts it to a c-contiguous array. 
>>> # Often, this is a good thing, but for some applications, the 
>>> # non-standard striding is intentional and important to preserve. 
>>> pickled = cPickle.dumps(x, protocol=cPickle.HIGHEST_PROTOCOL) 
>>> cPickle.loads(pickled).strides 
(12, 3, 1) 

>>> # This is indeed happening during serialization, not deserialization 
>>> pickletools.dis(pickled) 
... 
151: S  STRING  '\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b\x0c\x10\x14\r\x11\x15\x0e\x12\x16\x0f\x13\x17' 
... 

注: numpyのは、c-の連続またはFortran連続保存するのに十分スマートですが、それは酸洗やunpickle化全体のすべての非標準的なストライドパターンを保存しません。

+1

短い答えを、ありません。 –

答えて

3

私は考えることができる唯一の方法は、それを自分で行うことである。

# --------------------------------------------- 
import numpy 
from numpy.lib.stride_tricks import as_strided 
import cPickle 

def dumps(x, protocol=cPickle.HIGHEST_PROTOCOL): 
    # flatten that keep real data order 
    y = as_strided(x, shape=(x.size,), strides=(min(x.strides),)) 
    return cPickle.dumps([y,x.shape,x.strides],protocol=protocol) 

def loads(pickled): 
    y,shape,strides = cPickle.loads(pickled) 
    return as_strided(y,shape=shape,strides=strides) 

if __name__=='__main__': 
    x = numpy.arange(2*3*4, dtype='uint8').reshape((2,3,4)).transpose(0,2,1) 

    pickled = dumps(x) 
    y = loads(pickled) 

    print 'x strides =', x.strides 
    print 'y strides =', y.strides 
    print 'x==y:', (x==y).all() 
# --------------------------------------------- 

出力:

x strides = (12, 1, 4) 
y strides = (12, 1, 4) 
x==y: True