def initialize opts={}
      labels = opts[:labels]
      levels = opts[:levels]

      raise ArgumentError, 'Must specify both labels and levels' unless labels && levels
      raise ArgumentError, 'Labels and levels should be same size' if labels.size != levels.size
      raise ArgumentError, 'Incorrect labels and levels' if incorrect_fields?(labels, levels)

      @labels = labels
      @levels = levels.map { |e| e.map.with_index.to_h }
      self.name = opts[:name] unless opts[:name].nil?
    end
names and levels should be of same size. If size of Array `name` is less
or greater than size of array `levels` then it raises `SizeError`.
If user don't want to put name for particular level then user must put
empty string in that index of Array `name`.
For example there is multi_index of 3 levels and user don't want to name
level 0, then do multi_index.name = ['', 'level1_name1', 'level2_name']

@example

# set the name during initialization

mi = Daru::MultiIndex.new(
levels: [[:a,:b,:c], [:one, :two]],
labels: [[0,0,1,1,2,2], [0,1,0,1,0,1]], name: ['s1', 's2'])

# =>
# <Daru::MultiIndex(6x2)>
#   s1  s2
#    a one
#      two
#    b one
#      two
#    c one
#      two

# set new name

mi.name = ['k1', 'k2']
=> ["k1", "k2"]

mi
=>
#   #<Daru::MultiIndex(6x2)>
#   k1  k2
#    a one
#      two
#    b one
#      two
#    c one
#      two

# access the name

mi.name
=> ["k1", "k2"]

# If you don't want to name level 0

mi.name = ['', 'k2']
=> ["", "k2"]

mi
=>
#<Daru::MultiIndex(6x2)>
#       k2
#    a one
#      two
#    b one
#      two
#    c one
#      two