Skip to content

Commit 32fad57

Browse files
authored
Merge pull request #25158 from seberg/loadtxt-encoding
API: Make `encoding=None` the default in loadtxt
2 parents 706e9aa + 798a3d1 commit 32fad57

9 files changed

Lines changed: 81 additions & 59 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
``loadtxt`` and ``genfromtxt`` default to ``encoding=None``
2+
-----------------------------------------------------------
3+
``loadtxt`` and ``genfromtxt`` now both default to ``encoding=None``
4+
which may mainly modifies how ``converters`` work.
5+
These will now be passed ``str`` rather than ``bytes``, pass the
6+
encoding explicitly to always get the new or old behavior.
7+
For ``genfromtxt`` the change also means that returned values will now be
8+
unicode strings rather than bytes.

doc/source/user/basics.io.genfromtxt.rst

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Quite often, a single character marks the separation between columns. For
5858
example, comma-separated files (CSV) use a comma (``,``) or a semicolon
5959
(``;``) as delimiter::
6060

61-
>>> data = u"1, 2, 3\n4, 5, 6"
61+
>>> data = "1, 2, 3\n4, 5, 6"
6262
>>> np.genfromtxt(StringIO(data), delimiter=",")
6363
array([[1., 2., 3.],
6464
[4., 5., 6.]])
@@ -74,12 +74,12 @@ defined as a given number of characters. In that case, we need to set
7474
``delimiter`` to a single integer (if all the columns have the same
7575
size) or to a sequence of integers (if columns can have different sizes)::
7676

77-
>>> data = u" 1 2 3\n 4 5 67\n890123 4"
77+
>>> data = " 1 2 3\n 4 5 67\n890123 4"
7878
>>> np.genfromtxt(StringIO(data), delimiter=3)
7979
array([[ 1., 2., 3.],
8080
[ 4., 5., 67.],
8181
[890., 123., 4.]])
82-
>>> data = u"123456789\n 4 7 9\n 4567 9"
82+
>>> data = "123456789\n 4 7 9\n 4567 9"
8383
>>> np.genfromtxt(StringIO(data), delimiter=(4, 3, 2))
8484
array([[1234., 567., 89.],
8585
[ 4., 7., 9.],
@@ -94,7 +94,7 @@ individual entries are not stripped of leading nor trailing white spaces.
9494
This behavior can be overwritten by setting the optional argument
9595
``autostrip`` to a value of ``True``::
9696

97-
>>> data = u"1, abc , 2\n 3, xxx, 4"
97+
>>> data = "1, abc , 2\n 3, xxx, 4"
9898
>>> # Without autostrip
9999
>>> np.genfromtxt(StringIO(data), delimiter=",", dtype="|U5")
100100
array([['1', ' abc ', ' 2'],
@@ -114,7 +114,7 @@ string that marks the beginning of a comment. By default,
114114
occur anywhere on the line. Any character present after the comment
115115
marker(s) is simply ignored::
116116

117-
>>> data = u"""#
117+
>>> data = """#
118118
... # Skip me !
119119
... # Skip me too !
120120
... 1, 2
@@ -154,7 +154,7 @@ of lines to skip at the beginning of the file, before any other action is
154154
performed. Similarly, we can skip the last ``n`` lines of the file by
155155
using the ``skip_footer`` attribute and giving it a value of ``n``::
156156

157-
>>> data = u"\n".join(str(i) for i in range(10))
157+
>>> data = "\n".join(str(i) for i in range(10))
158158
>>> np.genfromtxt(StringIO(data),)
159159
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
160160
>>> np.genfromtxt(StringIO(data),
@@ -178,7 +178,7 @@ integers behave the same as regular Python negative indexes.
178178
For example, if we want to import only the first and the last columns, we
179179
can use ``usecols=(0, -1)``::
180180

181-
>>> data = u"1 2 3\n4 5 6"
181+
>>> data = "1 2 3\n4 5 6"
182182
>>> np.genfromtxt(StringIO(data), usecols=(0, -1))
183183
array([[1., 3.],
184184
[4., 6.]])
@@ -187,7 +187,7 @@ If the columns have names, we can also select which columns to import by
187187
giving their name to the ``usecols`` argument, either as a sequence
188188
of strings or a comma-separated string::
189189

190-
>>> data = u"1 2 3\n4 5 6"
190+
>>> data = "1 2 3\n4 5 6"
191191
>>> np.genfromtxt(StringIO(data),
192192
... names="a, b, c", usecols=("a", "c"))
193193
array([(1., 3.), (4., 6.)], dtype=[('a', '<f8'), ('c', '<f8')])
@@ -370,8 +370,8 @@ single element of the wanted type.
370370
In the following example, the second column is converted from as string
371371
representing a percentage to a float between 0 and 1::
372372

373-
>>> convertfunc = lambda x: float(x.strip(b"%"))/100.
374-
>>> data = u"1, 2.3%, 45.\n6, 78.9%, 0"
373+
>>> convertfunc = lambda x: float(x.strip("%"))/100.
374+
>>> data = "1, 2.3%, 45.\n6, 78.9%, 0"
375375
>>> names = ("i", "p", "n")
376376
>>> # General case .....
377377
>>> np.genfromtxt(StringIO(data), delimiter=",", names=names)
@@ -405,7 +405,7 @@ string into the corresponding float or into -999 if the string is empty.
405405
We need to explicitly strip the string from white spaces as it is not done
406406
by default::
407407

408-
>>> data = u"1, , 3\n 4, 5, 6"
408+
>>> data = "1, , 3\n 4, 5, 6"
409409
>>> convert = lambda x: float(x.strip() or -999)
410410
>>> np.genfromtxt(StringIO(data), delimiter=",",
411411
... converters={1: convert})
@@ -483,7 +483,7 @@ with ``"N/A"`` in the first column and by ``"???"`` in the third column.
483483
We wish to transform these missing values to 0 if they occur in the first
484484
and second column, and to -999 if they occur in the last column::
485485

486-
>>> data = u"N/A, 2, 3\n4, ,???"
486+
>>> data = "N/A, 2, 3\n4, ,???"
487487
>>> kwargs = dict(delimiter=",",
488488
... dtype=int,
489489
... names="a,b,c",

numpy/_core/code_generators/ufunc_docstrings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4279,10 +4279,10 @@ def add_newdoc(place, name, doc):
42794279
>>> a = np.array(['Grace Hopper Conference', 'Open Source Day'])
42804280
>>> np.char.str_len(a)
42814281
array([23, 15])
4282-
>>> a = np.array([u'\u0420', u'\u043e'])
4282+
>>> a = np.array(['\u0420', '\u043e'])
42834283
>>> np.char.str_len(a)
42844284
array([1, 1])
4285-
>>> a = np.array([['hello', 'world'], [u'\u0420', u'\u043e']])
4285+
>>> a = np.array([['hello', 'world'], ['\u0420', '\u043e']])
42864286
>>> np.char.str_len(a)
42874287
array([[5, 5], [1, 1]])
42884288

numpy/_core/defchararray.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,10 @@ def str_len(a):
285285
>>> a = np.array(['Grace Hopper Conference', 'Open Source Day'])
286286
>>> np.char.str_len(a)
287287
array([23, 15])
288-
>>> a = np.array([u'\u0420', u'\u043e'])
288+
>>> a = np.array(['\u0420', '\u043e'])
289289
>>> np.char.str_len(a)
290290
array([1, 1])
291-
>>> a = np.array([['hello', 'world'], [u'\u0420', u'\u043e']])
291+
>>> a = np.array([['hello', 'world'], ['\u0420', '\u043e']])
292292
>>> np.char.str_len(a)
293293
array([[5, 5], [1, 1]])
294294
"""

numpy/lib/_function_base_impl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,7 @@ def disp(mesg, device=None, linefeed=True):
19761976
19771977
>>> from io import StringIO
19781978
>>> buf = StringIO()
1979-
>>> np.disp(u'"Display" in a file', device=buf)
1979+
>>> np.disp('"Display" in a file', device=buf)
19801980
>>> buf.getvalue()
19811981
'"Display" in a file\\n'
19821982

numpy/lib/_npyio_impl.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ def _preprocess_comments(iterable, comments, encoding):
815815
def _read(fname, *, delimiter=',', comment='#', quote='"',
816816
imaginary_unit='j', usecols=None, skiplines=0,
817817
max_rows=None, converters=None, ndmin=None, unpack=False,
818-
dtype=np.float64, encoding="bytes"):
818+
dtype=np.float64, encoding=None):
819819
r"""
820820
Read a NumPy array from a text file.
821821
This is a helper function for loadtxt.
@@ -1073,7 +1073,7 @@ def _read(fname, *, delimiter=',', comment='#', quote='"',
10731073
@set_module('numpy')
10741074
def loadtxt(fname, dtype=float, comments='#', delimiter=None,
10751075
converters=None, skiprows=0, usecols=None, unpack=False,
1076-
ndmin=0, encoding='bytes', max_rows=None, *, quotechar=None,
1076+
ndmin=0, encoding=None, max_rows=None, *, quotechar=None,
10771077
like=None):
10781078
r"""
10791079
Load data from a text file.
@@ -1145,6 +1145,10 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
11451145
the system default is used. The default value is 'bytes'.
11461146
11471147
.. versionadded:: 1.14.0
1148+
.. versionchanged:: 2.0
1149+
Before NumPy 2, the default was ``'bytes'`` for Python 2
1150+
compatibility. The default is now ``None``.
1151+
11481152
max_rows : int, optional
11491153
Read `max_rows` rows of content after `skiprows` lines. The default is
11501154
to read all the rows. Note that empty rows containing no data such as
@@ -1262,24 +1266,22 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
12621266
array([1.e+00, 2.7e+00, 1.e+05])
12631267
12641268
This idea can be extended to automatically handle values specified in
1265-
many different formats:
1269+
many different formats, such as hex values:
12661270
12671271
>>> def conv(val):
12681272
... try:
12691273
... return float(val)
12701274
... except ValueError:
12711275
... return float.fromhex(val)
12721276
>>> s = StringIO("1, 2.5, 3_000, 0b4, 0x1.4000000000000p+2")
1273-
>>> np.loadtxt(s, delimiter=",", converters=conv, encoding=None)
1277+
>>> np.loadtxt(s, delimiter=",", converters=conv)
12741278
array([1.0e+00, 2.5e+00, 3.0e+03, 1.8e+02, 5.0e+00])
12751279
1276-
Note that with the default ``encoding="bytes"``, the inputs to the
1277-
converter function are latin-1 encoded byte strings. To deactivate the
1278-
implicit encoding prior to conversion, use ``encoding=None``
1280+
Or a format where the ``-`` sign comes after the number:
12791281
12801282
>>> s = StringIO('10.01 31.25-\n19.22 64.31\n17.57- 63.94')
12811283
>>> conv = lambda x: -float(x[:-1]) if x.endswith('-') else float(x)
1282-
>>> np.loadtxt(s, converters=conv, encoding=None)
1284+
>>> np.loadtxt(s, converters=conv)
12831285
array([[ 10.01, -31.25],
12841286
[ 19.22, 64.31],
12851287
[-17.57, 63.94]])
@@ -1715,7 +1717,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
17151717
deletechars=''.join(sorted(NameValidator.defaultdeletechars)),
17161718
replace_space='_', autostrip=False, case_sensitive=True,
17171719
defaultfmt="f%i", unpack=None, usemask=False, loose=True,
1718-
invalid_raise=True, max_rows=None, encoding='bytes',
1720+
invalid_raise=True, max_rows=None, encoding=None,
17191721
*, ndmin=0, like=None):
17201722
"""
17211723
Load data from a text file, with missing values handled as specified.
@@ -1816,6 +1818,10 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
18161818
The default value is 'bytes'.
18171819
18181820
.. versionadded:: 1.14.0
1821+
.. versionchanged:: 2.0
1822+
Before NumPy 2, the default was ``'bytes'`` for Python 2
1823+
compatibility. The default is now ``None``.
1824+
18191825
ndmin : int, optional
18201826
Same parameter as `loadtxt`
18211827
@@ -1858,7 +1864,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
18581864
18591865
Comma delimited file with mixed dtype
18601866
1861-
>>> s = StringIO(u"1,1.3,abcde")
1867+
>>> s = StringIO("1,1.3,abcde")
18621868
>>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'),
18631869
... ('mystring','S5')], delimiter=",")
18641870
>>> data
@@ -1885,7 +1891,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
18851891
18861892
An example with fixed-width columns
18871893
1888-
>>> s = StringIO(u"11.3abcde")
1894+
>>> s = StringIO("11.3abcde")
18891895
>>> data = np.genfromtxt(s, dtype=None, names=['intvar','fltvar','strvar'],
18901896
... delimiter=[1,3,5])
18911897
>>> data

0 commit comments

Comments
 (0)