From b3b4fcfa388569ae9386582364013409f6c2870b Mon Sep 17 00:00:00 2001 From: James Hiebert Date: Tue, 14 Apr 2015 15:29:55 -0400 Subject: [PATCH 1/2] BUG GH9057 Converted column names to strings before creating pytables metadata object --- pandas/io/pytables.py | 11 ++++++++++- pandas/tests/test_frame.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index 458a245da6bdb..ca7b62296bc5c 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -1766,7 +1766,7 @@ def set_kind(self): # set my typ if we need if self.typ is None: - self.typ = getattr(self.description, self.cname, None) + self.typ = getattr(self.description, str(self.cname), None) def set_atom(self, block, block_items, existing_col, min_itemsize, nan_rep, info, encoding=None, **kwargs): @@ -3018,6 +3018,8 @@ def write_metadata(self, key, values): def read_metadata(self, key): """ return the meta data array for this key """ + if str(key) != key: + key = str(key) if getattr(getattr(self.group,'meta',None),key,None) is not None: return self.parent.select(self._get_metadata_path(key)) return None @@ -3157,6 +3159,8 @@ def create_index(self, columns=None, optlevel=None, kind=None): table = self.table for c in columns: + if str(c) != c: + c = str(c) v = getattr(table.cols, c, None) if v is not None: @@ -3519,6 +3523,11 @@ def create_description(self, complib=None, complevel=None, # description from the axes & values d['description'] = dict([(a.cname, a.typ) for a in self.axes]) + # keys to pytables columns must be strings + for a in self.axes: + if str(a.cname) != a.cname: + d['description'][str(a.cname)] = d['description'].pop(a.cname) + if complib: if complevel is None: complevel = self._complevel or 9 diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index c7c35e63d3d91..2374fe0b5881d 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -5,6 +5,7 @@ from copy import deepcopy from datetime import datetime, timedelta, time import sys +import os import operator import re import csv @@ -13,6 +14,7 @@ import itertools from itertools import product, permutations from distutils.version import LooseVersion +from tempfile import NamedTemporaryFile from pandas.compat import( map, zip, range, long, lrange, lmap, lzip, @@ -14204,6 +14206,35 @@ def _constructor(self): # GH9776 self.assertEqual(df.iloc[0:1, :].testattr, 'XXX') +def skip_if_no_pytables(): + try: + import tables + except ImportError: + raise nose.SkipTest("cannot check test results without pytables") + + +class TestToHdfWithIntegerColumnNames(tm.TestCase): + # GH9057 + def setUp(self): + N = 2 + array = np.random.randint(0,8, size=N*N).astype('uint8').reshape(N,-1) + df = DataFrame(array, index=pd.date_range('20130206', + periods=N,freq='ms')) + + self.filename = NamedTemporaryFile(suffix='.h5', delete=False).name + df.to_hdf(self.filename,'df', mode='w', format='table', + data_columns=True) + + def test_file_is_openable(self): + skip_if_no_pytables() + import tables + + with tables.open_file(self.filename, 'r') as myfile: + stuff = myfile.root.df + assert stuff + + def tearDown(self): + os.remove(self.filename) def skip_if_no_ne(engine='numexpr'): if engine == 'numexpr': From d8dac7431aabac74b7556dd9457efefe1b3c5476 Mon Sep 17 00:00:00 2001 From: James Hiebert Date: Tue, 14 Apr 2015 21:50:20 -0400 Subject: [PATCH 2/2] Moved test from pandas/tests/test_frame.py to pandas/io/test_pytables.py --- pandas/io/tests/test_pytables.py | 22 ++++++++++++++++++++++ pandas/tests/test_frame.py | 31 ------------------------------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/pandas/io/tests/test_pytables.py b/pandas/io/tests/test_pytables.py index 03e7a8eae549d..ef06f0a000ba5 100644 --- a/pandas/io/tests/test_pytables.py +++ b/pandas/io/tests/test_pytables.py @@ -4,6 +4,7 @@ import warnings import tempfile from contextlib import contextmanager +from tempfile import NamedTemporaryFile import datetime import numpy as np @@ -4623,6 +4624,27 @@ def _test_sort(obj): else: raise ValueError('type not supported here') +class TestToHdfWithIntegerColumnNames(tm.TestCase): + # GH9057 + def setUp(self): + N = 2 + array = np.random.randint(0,8, size=N*N).astype('uint8').reshape(N,-1) + df = DataFrame(array, index=pd.date_range('20130206', + periods=N,freq='ms')) + + self.filename = NamedTemporaryFile(suffix='.h5', delete=False).name + df.to_hdf(self.filename,'df', mode='w', format='table', + data_columns=True) + + def test_file_is_openable(self): + + with tables.open_file(self.filename, 'r') as myfile: + stuff = myfile.root.df + assert stuff + + def tearDown(self): + os.remove(self.filename) + if __name__ == '__main__': import nose diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 2374fe0b5881d..1067711acdb52 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -14,7 +14,6 @@ import itertools from itertools import product, permutations from distutils.version import LooseVersion -from tempfile import NamedTemporaryFile from pandas.compat import( map, zip, range, long, lrange, lmap, lzip, @@ -14206,36 +14205,6 @@ def _constructor(self): # GH9776 self.assertEqual(df.iloc[0:1, :].testattr, 'XXX') -def skip_if_no_pytables(): - try: - import tables - except ImportError: - raise nose.SkipTest("cannot check test results without pytables") - - -class TestToHdfWithIntegerColumnNames(tm.TestCase): - # GH9057 - def setUp(self): - N = 2 - array = np.random.randint(0,8, size=N*N).astype('uint8').reshape(N,-1) - df = DataFrame(array, index=pd.date_range('20130206', - periods=N,freq='ms')) - - self.filename = NamedTemporaryFile(suffix='.h5', delete=False).name - df.to_hdf(self.filename,'df', mode='w', format='table', - data_columns=True) - - def test_file_is_openable(self): - skip_if_no_pytables() - import tables - - with tables.open_file(self.filename, 'r') as myfile: - stuff = myfile.root.df - assert stuff - - def tearDown(self): - os.remove(self.filename) - def skip_if_no_ne(engine='numexpr'): if engine == 'numexpr': try: