I suggest you do that as follows:
my_array = [["Alaska" ,"Rain","3"], ["Alaska", "Snow","4"],
["Alabama","Snow","2"], ["Alabama","Hail","1"]]
attributes = my_array.transpose[1].uniq
#=> ["Rain", "Snow", "Hail"]
h = my_array.each_with_object({}) { |a,h| (h[a.first] ||= {})[a[1]] = a[2].to_i }
#=> {"Alaska" =>{"Rain"=>3, "Snow"=>4},
# "Alabama"=>{"Snow"=>2, "Hail"=>1}}
[["State", *attributes], *h.map { |k,v| [k, *v.values_at(*attributes)] }]
#=> [["State", "Rain", "Snow", "Hail"],
# ["Alaska", 3, 4, nil],
# ["Alabama", nil, 2, 1]]
You can, of course, substitute out h.
Let's look more carefully at the calculation of:
h.map { |k,v| [k, *v.values_at(*attributes)] }]
We have:
enum = h.map
#=> #<Enumerator: {"Alaska"=>{"Rain"=>3, "Snow"=>4},
# "Alabama"=>{"Snow"=>2, "Hail"=>1}}:map>
The first element of the enumerator is passed into the block by Enumerator#each:
k,v = enum.next
#=> ["Alaska", {"Rain"=>3, "Snow"=>4}]
k #=> "Alaska"
v #=> {"Rain"=>3, "Snow"=>4}
b = v.values_at(*attributes)
#=> {"Rain"=>3, "Snow"=>4}.values_at(*["Rain", "Snow", "Hail"])
#=> {"Rain"=>3, "Snow"=>4}.values_at("Rain", "Snow", "Hail")
#=> [3, 4, nil]
[k, *b]
#=> ["Alaska", *[3, 4, nil]]
#=> ["Alaska", 3, 4, nil]
The second element of enum is passed into the block:
k,v = enum.next
#=> ["Alabama", {"Snow"=>2, "Hail"=>1}]
b = v.values_at(*attributes)
#=> [nil, 2, 1]
[k, *b]
#=> ["Alabama", nil, 2, 1]