Module: Npy

Defined in:
lib/npy.rb,
lib/npy/file.rb,
lib/npy/version.rb

Defined Under Namespace

Classes: Error, File

Constant Summary collapse

MAGIC_STR =
"\x93NUMPY".b
TYPE_MAP =
{
  "|i1" => Numo::Int8,
  "<i2" => Numo::Int16,
  "<i4" => Numo::Int32,
  "<i8" => Numo::Int64,
  "|u1" => Numo::UInt8,
  "<u2" => Numo::UInt16,
  "<u4" => Numo::UInt32,
  "<u8" => Numo::UInt64,
  "<f4" => Numo::SFloat,
  "<f8" => Numo::DFloat,
  "<c8" => Numo::SComplex,
  "<c16" => Numo::DComplex
}
VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.load(path) ⇒ Object



30
31
32
33
34
# File 'lib/npy.rb', line 30

def load(path)
  with_file(path) do |f|
    load_io(f)
  end
end

.load_io(io) ⇒ Object

rubyzip not playing nicely with StringIO def load_npz_string(byte_str)

load_npz_io(StringIO.new(byte_str))

end

Raises:



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
# File 'lib/npy.rb', line 51

def load_io(io)
  magic = io.read(6)
  raise Error, "Invalid npy format" unless magic&.b == MAGIC_STR

  version = io.read(2)

  header_len =
    case version
    when "\x01\x00".b
      io.read(2).unpack1("S<")
    when "\x02\x00".b, "\x03\x00".b
      io.read(4).unpack1("I<")
    else
      raise Error, "Unsupported version"
    end
  header = io.read(header_len)
  descr, fortran_order, shape = parse_header(header)
  raise Error, "Fortran order not supported" if fortran_order

  # numo can't handle empty shapes
  empty_shape = shape.empty?
  shape = [1] if empty_shape

  klass = TYPE_MAP[descr]
  raise Error, "Type not supported: #{descr}" unless klass

  # use from_string instead of from_binary for max compatibility
  # from_binary introduced in 0.9.0.4
  result = klass.from_string(io.read, shape)
  result = result[0] if empty_shape
  result
end

.load_npz(path) ⇒ Object



36
37
38
39
40
# File 'lib/npy.rb', line 36

def load_npz(path)
  with_file(path) do |f|
    load_npz_io(f)
  end
end

.load_npz_io(io) ⇒ Object



84
85
86
# File 'lib/npy.rb', line 84

def load_npz_io(io)
  File.new(io)
end

.load_string(byte_str) ⇒ Object



42
43
44
# File 'lib/npy.rb', line 42

def load_string(byte_str)
  load_io(StringIO.new(byte_str))
end

.save(path, arr) ⇒ Object



88
89
90
91
92
93
# File 'lib/npy.rb', line 88

def save(path, arr)
  ::File.open(path, "wb") do |f|
    save_io(f, arr)
  end
  true
end

.save_npz(path, **arrs) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/npy.rb', line 95

def save_npz(path, **arrs)
  # use File.open instead passing path to zip file
  # so it overrides instead of appends
  ::File.open(path, "wb") do |f|
    Zip::File.open(f, Zip::File::CREATE) do |zipfile|
      arrs.each do |k, v|
        zipfile.get_output_stream("#{k}.npy") do |f2|
          save_io(f2, v)
        end
      end
    end
  end
  true
end