2014-02-06 2 views
0

У меня есть таблица в HDFStore с колонкой с поплавками f, хранящейся как data_column. Я хотел бы выбрать подмножество строк, где, например, f==0.6.Выбор данных из HDFStore с помощью плавающей запятой data_column

Я столкнулся с проблемами, которые, как я предполагаю, связан с некорректным рассогласованием с плавающей точкой. Вот пример:

In [1]: f = np.arange(0, 1, 0.1) 

In [2]: s = f.astype('S') 

In [3]: df = pd.DataFrame({'f': f, 's': s}) 

In [4]: df 
Out[4]: 
    f s 
0 0.0 0.0 
1 0.1 0.1 
2 0.2 0.2 
3 0.3 0.3 
4 0.4 0.4 
5 0.5 0.5 
6 0.6 0.6 
7 0.7 0.7 
8 0.8 0.8 
9 0.9 0.9 

[10 rows x 2 columns] 

In [5]: with pd.get_store('test.h5', mode='w') as store: 
    ...:  store.append('df', df, data_columns=True) 
    ...:  

In [6]: with pd.get_store('test.h5', mode='r') as store: 
    ...:  selection = store.select('df', 'f=f') 
    ...:  

In [7]: selection 
Out[7]: 
    f s 
0 0.0 0.0 
1 0.1 0.1 
2 0.2 0.2 
4 0.4 0.4 
5 0.5 0.5 
8 0.8 0.8 
9 0.9 0.9 

[7 rows x 2 columns] 

Я хотел бы, чтобы запрос возвращал все строки, но вместо этого некоторые из них отсутствовали. Запрос с where='f=0.3' возвращает пустую таблицу:

In [8]: with pd.get_store('test.h5', mode='r') as store: 
    selection = store.select('df', 'f=0.3') 
    ...:  

In [9]: selection 
Out[9]: 
Empty DataFrame 
Columns: [f, s] 
Index: [] 

[0 rows x 2 columns] 

Я задаюсь вопросом, является ли предполагаемое поведение, и если да, то есть простой обходной путь, например, устанавливая предел точности с плавающей точкой запросов в панд ? Я использую версию 0.13.1:

In [10]: pd.__version__ 
Out[10]: '0.13.1-55-g7d3e41c' 

ответ

3

Я так не думаю, нет. Pandas построена вокруг numpy, и я никогда не видел никаких инструментов для приблизительного равенства float, кроме тестовых утилит, таких как assert_allclose, и это не поможет.

Лучшее, что вы можете сделать, это что-то вроде:

In [17]: with pd.get_store('test.h5', mode='r') as store: 
     selection = store.select('df', '(f > 0.2) & (f < 0.4)') 
    ....:  

In [18]: selection 
Out[18]: 
    f s 
3 0.3 0.3 

Если это общая идиома для вас, сделать функцию для него. Вы можете даже получить фантазию, включив numpy float precision.

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