We looked a little into this and it seems like the byte string interface will preserve NAN. We're going to dig deeper into the serialization code for a fix.
Anyway, here is a code snippet for using the byte string interface. The byte string can be pickled, so a workaround for flex would be to add an extra conversion step to byte string before pickling.
from __future__ import print_function
import pickle
from scitbx.array_family import flex
# NAN in flex.double
a = flex.random_double(5)
n = float('nan')
a[3] = n
# pickle test
p = pickle.dumps(a)
ap = pickle.loads(p)
# byte string test
b = a.copy_to_byte_str()
ab = flex.double_from_byte_str(b)
# pickled byte string test
pb = pickle.dumps(b)
apb = flex.double_from_byte_str(pickle.loads(pb))
# check arrays
print('Original:', list(a))
print('Pickle: ', list(ap), 'Oh no!')
print('Bytes: ', list(ab))
print('Bytes2: ', list(apb))