diff --git a/doc/source/whatsnew/v1.4.3.rst b/doc/source/whatsnew/v1.4.3.rst index d53acc698c3bb..8572c136c28a9 100644 --- a/doc/source/whatsnew/v1.4.3.rst +++ b/doc/source/whatsnew/v1.4.3.rst @@ -14,7 +14,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ -- +- Fixed regression in :func:`read_fwf` raising ``ValueError`` when ``widths`` was specified with ``usecols`` (:issue:`46580`) - .. --------------------------------------------------------------------------- diff --git a/pandas/io/parsers/readers.py b/pandas/io/parsers/readers.py index c639f408c75f5..f853251d599d2 100644 --- a/pandas/io/parsers/readers.py +++ b/pandas/io/parsers/readers.py @@ -1354,7 +1354,8 @@ def read_fwf( len_index = 1 else: len_index = len(index_col) - if len(names) + len_index != len(colspecs): + if kwds.get("usecols") is None and len(names) + len_index != len(colspecs): + # If usecols is used colspec may be longer than names raise ValueError("Length of colspecs must match length of names") kwds["colspecs"] = colspecs diff --git a/pandas/tests/io/parser/test_read_fwf.py b/pandas/tests/io/parser/test_read_fwf.py index 3de73e51ce6b6..f3d41332502af 100644 --- a/pandas/tests/io/parser/test_read_fwf.py +++ b/pandas/tests/io/parser/test_read_fwf.py @@ -930,3 +930,26 @@ def test_names_and_infer_colspecs(): result = read_fwf(StringIO(data), skiprows=1, usecols=[0, 2], names=["a", "b"]) expected = DataFrame({"a": [959.0], "b": 22.2}) tm.assert_frame_equal(result, expected) + + +def test_widths_and_usecols(): + # GH#46580 + data = """0 1 n -0.4100.1 +0 2 p 0.2 90.1 +0 3 n -0.3140.4""" + result = read_fwf( + StringIO(data), + header=None, + usecols=(0, 1, 3), + widths=(3, 5, 1, 5, 5), + index_col=False, + names=("c0", "c1", "c3"), + ) + expected = DataFrame( + { + "c0": 0, + "c1": [1, 2, 3], + "c3": [-0.4, 0.2, -0.3], + } + ) + tm.assert_frame_equal(result, expected)