ENH: usecols now accepts an int when only one column has to be read by I--P · Pull Request #6656 · numpy/numpy · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/release/1.12.0-notes.rst
35 changes: 30 additions & 5 deletions numpy/lib/npyio.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import itertools
import warnings
import weakref
from operator import itemgetter
from operator import itemgetter, index as opindex

import numpy as np
from . import format
Expand Down Expand Up @@ -714,10 +714,18 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
``converters = {3: lambda s: float(s.strip() or 0)}``. Default: None.
skiprows : int, optional
Skip the first `skiprows` lines; default: 0.
usecols : sequence, optional
Which columns to read, with 0 being the first. For example,
``usecols = (1,4,5)`` will extract the 2nd, 5th and 6th columns.

usecols : int or sequence, optional
Which columns to read, with 0 being the first. For example,
usecols = (1,4,5) will extract the 2nd, 5th and 6th columns.
The default, None, results in all columns being read.

.. versionadded:: 1.11.0

Also when a single column has to be read it is possible to use
an integer instead of a tuple. E.g ``usecols = 3`` reads the
third column the same way as `usecols = (3,)`` would.

unpack : bool, optional
If True, the returned array is transposed, so that arguments may be
unpacked using ``x, y, z = loadtxt(...)``. When used with a structured
Expand Down Expand Up @@ -786,8 +794,25 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
user_converters = converters
if delimiter is not None:
delimiter = asbytes(delimiter)

if usecols is not None:
usecols = list(usecols)
# Allow usecols to be a single int or a sequence of ints
try:
usecols_as_list = list(usecols)
except TypeError:
usecols_as_list = [usecols]
for col_idx in usecols_as_list:
try:
opindex(col_idx)
except TypeError as e:
e.args = (
"usecols must be an int or a sequence of ints but "
"it contains at least one element of type %s" %
type(col_idx),
)
raise
# Fall back to existing code
usecols = usecols_as_list

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think there is no reason to create usecols_as_list at all. Also the comment is rather unnecessary "existing code" is not existing code anymore as soon as we put this in ;).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By existing code I meant all the lines below this one where usecols is used.
You're right I can use usecols and avoid the creation of usecols_as_list. I wished to make this easier to read, I hate code like foo=some_fancy_type(foo) buried deep in some code and then waste time trying to understand why foo is not any more what it was at the beginning.


fown = False
try:
Expand Down
38 changes: 38 additions & 0 deletions numpy/lib/tests/test_io.py