2014-01-26 3 views
0

У меня есть dataframe панды, названный «impression_data», который включает в себя колонку под названием «site.id», как это:Членство тестирования поплавков в панде Int64 dataframe производит неожиданный результат

>>> impression_data['site.id'] 

0  62 
1  189 
2  191 
3  62 
... 

Каждый элемент в этом столбец имеет тип данных numpy.int64, как это:

>>> for i in impression_data['site.id']: 
    print type(i) 

<type 'numpy.int64'> 
<type 'numpy.int64'> 
<type 'numpy.int64'> 
... 

И, как и ожидалось, тестирование членов работает хорошо, пока я проверяю целых чисел:

>>> 62 in impression_data['site.id'] 
True 

Но вот неожиданный результат: у меня создалось впечатление, что столбец np.int64 не должен содержать никаких десятичных значений. Видимо, я ошибаюсь. Что тут происходит?

>>> 62.5 in impression_data['site.id'] 
True 

Edit 1: Все значения в столбце должны быть целыми числами по построению. Для полноты картины, я также выполнены следующие операции литья и возникало никаких ошибок:

impression_data['site.id'] = impression_data['site.id'].astype('int') 

В соответствии с @ BremBam-х предложений в комментариях, я попытался

impression_data['site.id'].map(type).unique() 

который производит

[<type 'numpy.int64'>] 

Минимальный пример и реальный файл данных, с которыми я работаю, приведены здесь https://dl.dropboxusercontent.com/u/28347262/SE%20Pandas%20Int64%20Membership%20Testing/cm_impression.csv

и здесь

https://dl.dropboxusercontent.com/u/28347262/SE%20Pandas%20Int64%20Membership%20Testing/ExampleCode.py

+0

Вы уверены, что каждое значение является int? Что делает 'impression_data ['site.id']. Map (type) .unique()' give? Можете ли вы предоставить пример кода и данных, которые демонстрируют проблему? – BrenBarn

+0

Спасибо за ваш быстрый ответ, @BrenBarn. Я принял ваш совет по попытке «impression_data ['site.id']. Map (type) .unique()' и отредактировал мой вопрос, чтобы это отразить. Пример кода и данных, которые следует выполнить в ближайшее время. – avn2109

+0

Исторически использование 'in' для массивов numpy может давать нечетные результаты - я бы предложил что-то вроде' np.any (df ['site.id']. Isin ([62.5])). – Daniel

ответ

1

Это a bug in pandas. Значение передается типу индекса перед проведением теста на локализацию, поэтому 62.5 преобразуется в 62. (Обратите внимание, что in за серию проверяет, находится ли значение в индекса, а не значения.)

Я считаю, что вы можете получить то, что вы хотите, делая 62.5 in impression_data.values.

+0

'62.5 in impression_data ['site.id']. Values' производит' False', точно так же, как вы прогнозируете. Легкое исправление! – avn2109

+0

@ avn2109 Обратите внимание, что использование 'in' с массивами numpy не всегда дает желаемый результат, особенно когда массив numpy имеет более одного измерения. Будьте очень осторожны. – Daniel

+0

@Ophion: Вы можете уточнить? В любом случае здесь мы используем только 1D-массив (в виде серии). – BrenBarn

0

Во-первых, статус испытания в серии из индекса, а не значения:

>>> s = pd.Series([10,20,30]) 
>>> s 
0 10 
1 20 
2 30 
dtype: int64 
>>> 0 in s 
True 
>>> 10 in s 
False 

Но вы правы:

>>> 1.5 in s 
True 

После некоторых работ это видно мс, чтобы быть из-за __contains__ в Int64HashTable:

cdef class Int64HashTable: #(HashTable): 
    [...] 
    def __contains__(self, object key): 
     cdef khiter_t k 
     k = kh_get_int64(self.table, key) 
     return k != self.table.n_buckets 

key приходит как поплавок, но у нас есть

inline khint_t kh_get_int64(kh_int64_t*, int64_t) 

и поэтому я думаю, что принужден к целому до сравнение.

+0

Спасибо, что указали мою ошибку с индексом @DSM. Это может вызвать множество проблем. – avn2109

Смежные вопросы