NumPy array as quasi-hash table
I think this looks pretty efficient.  Let me add a few more minor, detailed comments (more than 1 year after the question was asked; I hope they are still useful):


After you convert to a NumPy array, the keys are longer guaranteed to be unique (if someone re-uses your code in a different context, etc).  This will cause searchsorted to fail.  You might want to add a check such as:

assert len(self.data[:, 0]) == len(np.unique(self.data[:, 0])


to make sure users and readers of your code know that the first column of your array must be unique.
I agree that record arrays (aka structured arrays) would be better.  Your code would be more readable because instead of things like:

self.data[ix][1:]


you could write:

self.data[ix]['Float_1'], self.data[ix]['Float_2']


(but please use more descriptive names for your context than 'Float_1 etc.!)

Also, and more importantly: without using a structured array, your hash keys will be stored as floats instead of ints.  That will take extra memory, and make future calls to searchsorted and __eq slightly less efficient.
Your __contains__ method seems overly stringent to me, which would result in it being slower.  Do you need to call searcshorted in __contains__ at all?  Wouldn't something like this suffice and be more efficient?

def __contains__(self, key):
    hkey = hash(key)
    return np.in1d(self.data[:, 0], hkey).any()

You are duplicating the __contains__ check in your __getitem__ code.  I'd just say it this way:

if __contains__(self, key): return self.data[ix][1:]

Very minor, but the idiom is always import numpy as np.  It's probably best to use that so you can do np.searchsorted etc. instead of typing numpy.searchsorted as that's what most NumPy users do.