Printing tables doesn't work correctly with 0-length array cells
See original GitHub issueDescription
I have data in form of a list of dictionaries. Each dictionary contains some items with an integer value and some of these items set the length for 1 or more array values.
I am creating a Table using the rows
attribute and feeding to it the list of dictionaries.
As long as I create a table until the first event with data in the array fields the table gets printed correctly. If I fill the table only with events with null array data (but the rest of the fields have something to show) I get an IndexError.
Expected behavior
The table should print fine also when there are only “bad” events
Actual behavior
I get the following error Traceback
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/IPython/core/formatters.py:707, in PlainTextFormatter.__call__(self, obj)
700 stream = StringIO()
701 printer = pretty.RepresentationPrinter(stream, self.verbose,
702 self.max_width, self.newline,
703 max_seq_length=self.max_seq_length,
704 singleton_pprinters=self.singleton_printers,
705 type_pprinters=self.type_printers,
706 deferred_pprinters=self.deferred_printers)
--> 707 printer.pretty(obj)
708 printer.flush()
709 return stream.getvalue()
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/IPython/lib/pretty.py:410, in RepresentationPrinter.pretty(self, obj)
407 return meth(obj, self, cycle)
408 if cls is not object \
409 and callable(cls.__dict__.get('__repr__')):
--> 410 return _repr_pprint(obj, self, cycle)
412 return _default_pprint(obj, self, cycle)
413 finally:
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/IPython/lib/pretty.py:778, in _repr_pprint(obj, p, cycle)
776 """A pprint that just redirects to the normal repr function."""
777 # Find newlines and replace them with p.break_()
--> 778 output = repr(obj)
779 lines = output.splitlines()
780 with p.group():
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/table.py:1534, in Table.__repr__(self)
1533 def __repr__(self):
-> 1534 return self._base_repr_(html=False, max_width=None)
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/table.py:1516, in Table._base_repr_(self, html, descr_vals, max_width, tableid, show_dtype, max_lines, tableclass)
1513 if tableid is None:
1514 tableid = f'table{id(self)}'
-> 1516 data_lines, outs = self.formatter._pformat_table(
1517 self, tableid=tableid, html=html, max_width=max_width,
1518 show_name=True, show_unit=None, show_dtype=show_dtype,
1519 max_lines=max_lines, tableclass=tableclass)
1521 out = descr + '\n'.join(data_lines)
1523 return out
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:589, in TableFormatter._pformat_table(self, table, max_lines, max_width, show_name, show_unit, show_dtype, html, tableid, tableclass, align)
586 if col.info.name not in pprint_include_names:
587 continue
--> 589 lines, outs = self._pformat_col(col, max_lines, show_name=show_name,
590 show_unit=show_unit, show_dtype=show_dtype,
591 align=align_)
592 if outs['show_length']:
593 lines = lines[:-1]
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:276, in TableFormatter._pformat_col(self, col, max_lines, show_name, show_unit, show_dtype, show_length, html, align)
268 col_strs_iter = self._pformat_col_iter(col, max_lines, show_name=show_name,
269 show_unit=show_unit,
270 show_dtype=show_dtype,
271 show_length=show_length,
272 outs=outs)
274 # Replace tab and newline with text representations so they display nicely.
275 # Newline in particular is a problem in a multicolumn table.
--> 276 col_strs = [val.replace('\t', '\\t').replace('\n', '\\n') for val in col_strs_iter]
277 if len(col_strs) > 0:
278 col_width = max(len(x) for x in col_strs)
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:276, in <listcomp>(.0)
268 col_strs_iter = self._pformat_col_iter(col, max_lines, show_name=show_name,
269 show_unit=show_unit,
270 show_dtype=show_dtype,
271 show_length=show_length,
272 outs=outs)
274 # Replace tab and newline with text representations so they display nicely.
275 # Newline in particular is a problem in a multicolumn table.
--> 276 col_strs = [val.replace('\t', '\\t').replace('\n', '\\n') for val in col_strs_iter]
277 if len(col_strs) > 0:
278 col_width = max(len(x) for x in col_strs)
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:493, in TableFormatter._pformat_col_iter(self, col, max_lines, show_name, show_unit, outs, show_dtype, show_length)
491 else:
492 try:
--> 493 yield format_col_str(idx)
494 except ValueError:
495 raise ValueError(
496 'Unable to parse format string "{}" for entry "{}" '
497 'in column "{}"'.format(col_format, col[idx],
498 col.info.name))
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:481, in TableFormatter._pformat_col_iter.<locals>.format_col_str(idx)
479 return format_func(col_format, col[(idx,) + multidim0])
480 else:
--> 481 left = format_func(col_format, col[(idx,) + multidim0])
482 right = format_func(col_format, col[(idx,) + multidim1])
483 return f'{left} .. {right}'
File astropy/table/_column_mixins.pyx:74, in astropy.table._column_mixins._ColumnGetitemShim.__getitem__()
File astropy/table/_column_mixins.pyx:57, in astropy.table._column_mixins.base_getitem()
File astropy/table/_column_mixins.pyx:69, in astropy.table._column_mixins.column_getitem()
IndexError: index 0 is out of bounds for axis 1 with size 0
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
341 method = get_real_method(obj, self.print_method)
342 if method is not None:
--> 343 return method()
344 return None
345 else:
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/table.py:1526, in Table._repr_html_(self)
1525 def _repr_html_(self):
-> 1526 out = self._base_repr_(html=True, max_width=-1,
1527 tableclass=conf.default_notebook_table_class)
1528 # Wrap <table> in <div>. This follows the pattern in pandas and allows
1529 # table to be scrollable horizontally in VS Code notebook display.
1530 out = f'<div>{out}</div>'
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/table.py:1516, in Table._base_repr_(self, html, descr_vals, max_width, tableid, show_dtype, max_lines, tableclass)
1513 if tableid is None:
1514 tableid = f'table{id(self)}'
-> 1516 data_lines, outs = self.formatter._pformat_table(
1517 self, tableid=tableid, html=html, max_width=max_width,
1518 show_name=True, show_unit=None, show_dtype=show_dtype,
1519 max_lines=max_lines, tableclass=tableclass)
1521 out = descr + '\n'.join(data_lines)
1523 return out
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:589, in TableFormatter._pformat_table(self, table, max_lines, max_width, show_name, show_unit, show_dtype, html, tableid, tableclass, align)
586 if col.info.name not in pprint_include_names:
587 continue
--> 589 lines, outs = self._pformat_col(col, max_lines, show_name=show_name,
590 show_unit=show_unit, show_dtype=show_dtype,
591 align=align_)
592 if outs['show_length']:
593 lines = lines[:-1]
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:276, in TableFormatter._pformat_col(self, col, max_lines, show_name, show_unit, show_dtype, show_length, html, align)
268 col_strs_iter = self._pformat_col_iter(col, max_lines, show_name=show_name,
269 show_unit=show_unit,
270 show_dtype=show_dtype,
271 show_length=show_length,
272 outs=outs)
274 # Replace tab and newline with text representations so they display nicely.
275 # Newline in particular is a problem in a multicolumn table.
--> 276 col_strs = [val.replace('\t', '\\t').replace('\n', '\\n') for val in col_strs_iter]
277 if len(col_strs) > 0:
278 col_width = max(len(x) for x in col_strs)
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:276, in <listcomp>(.0)
268 col_strs_iter = self._pformat_col_iter(col, max_lines, show_name=show_name,
269 show_unit=show_unit,
270 show_dtype=show_dtype,
271 show_length=show_length,
272 outs=outs)
274 # Replace tab and newline with text representations so they display nicely.
275 # Newline in particular is a problem in a multicolumn table.
--> 276 col_strs = [val.replace('\t', '\\t').replace('\n', '\\n') for val in col_strs_iter]
277 if len(col_strs) > 0:
278 col_width = max(len(x) for x in col_strs)
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:493, in TableFormatter._pformat_col_iter(self, col, max_lines, show_name, show_unit, outs, show_dtype, show_length)
491 else:
492 try:
--> 493 yield format_col_str(idx)
494 except ValueError:
495 raise ValueError(
496 'Unable to parse format string "{}" for entry "{}" '
497 'in column "{}"'.format(col_format, col[idx],
498 col.info.name))
File ~/Applications/mambaforge/envs/swgo/lib/python3.9/site-packages/astropy/table/pprint.py:481, in TableFormatter._pformat_col_iter.<locals>.format_col_str(idx)
479 return format_func(col_format, col[(idx,) + multidim0])
480 else:
--> 481 left = format_func(col_format, col[(idx,) + multidim0])
482 right = format_func(col_format, col[(idx,) + multidim1])
483 return f'{left} .. {right}'
File astropy/table/_column_mixins.pyx:74, in astropy.table._column_mixins._ColumnGetitemShim.__getitem__()
File astropy/table/_column_mixins.pyx:57, in astropy.table._column_mixins.base_getitem()
File astropy/table/_column_mixins.pyx:69, in astropy.table._column_mixins.column_getitem()
IndexError: index 0 is out of bounds for axis 1 with size 0
Steps to Reproduce
This is an example dataset: field “B” set the length of field “C”, so the first 2 events have an empty array in “C”
events = [{"A":0,"B":0, "C":np.array([], dtype=np.uint64)},
{"A":1,"B":0, "C":np.array([], dtype=np.uint64)},
{"A":2,"B":2, "C":np.array([0,1], dtype=np.uint64)}]
Showing just the first event prints the column names as a column,
Printing the first 2 throws the Traceback above
QTable(rows=events[:2])
Plotting all 3 events works
System Details
macOS-11.7-x86_64-i386-64bit Python 3.9.13 | packaged by conda-forge | (main, May 27 2022, 17:00:52) [Clang 13.0.1 ] Numpy 1.23.3 pyerfa 2.0.0.1 astropy 5.1 Scipy 1.9.1 Matplotlib 3.6.0
Issue Analytics
- State:
- Created a year ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
The last example you show is expected. The
rows=..
requires a list of rows and you passed a single dict. This is equivalent toTable(rows=["a", "b", "c"])
(three rows of a single column). There could be better input validation, but what you want to pass isrows=events[0:1]
.See #13838 for a fix to the root cause problem. You will still need to be careful about creating an object array with all empty lists.