Skip to main content
v2026.11,858 entries · CC-BY 4.0

numpy.loadtxt: Load a Text or CSV File into an Array

How numpy.loadtxt reads CSV and text files into arrays: arguments, documented examples, version changes since 1.23 and 2.0, and when to use genfromtxt.

Written and maintained by CASRAI Editorial Board

Last updated

numpy.loadtxt reads a plain-text file, such as a CSV, a tab-separated export or a whitespace-aligned instrument dump, and returns a NumPy array. The NumPy manual describes it as a function that “aims to be a fast reader for simply formatted files”. This guide covers the arguments you will actually use, shows the documented examples with their output, and sets out when to switch to numpy.genfromtxt instead. It also records which behaviours changed between NumPy versions, because many tutorials still describe the older ones.

What numpy.loadtxt is used for in research

Research data often arrives as a text file: a plate-reader export, a sensor log, a table of simulation output, or a CSV saved from a spreadsheet. When every row has the same number of values and nothing is missing, loadtxt turns that file into an array in one call, ready for plotting or numerical analysis. The same function accepts a file object, a path string, a pathlib.Path, a list of strings or a generator, and if the file name ends in .gz or .bz2 the file is decompressed first.

Instrument and lab files often begin with comment-prefixed metadata lines. By default loadtxt treats everything after a # as a comment, and skiprows lets you drop a fixed number of leading lines (comments included) before parsing begins. If you are still deciding how to clean data before analysis, see the CASRAI guides on data cleaning steps and data wrangling.

Install or access

loadtxt ships with NumPy, so installing NumPy is all that is needed. The NumPy installation page gives these routes:

  • pip: pip install numpy
  • conda: conda create -n my-env, then conda activate my-env, then conda install numpy
  • virtual environment: python -m venv my-env, then source my-env/bin/activate on macOS or Linux (my-env\Scripts\activate on Windows), then pip install numpy

To confirm the install, run import numpy as np; print(np.__version__). The version matters here, because the default for encoding changed in NumPy 2.0 (see the version table below).

Step-by-step: load a text file into an array

The signature in the current NumPy manual is:

numpy.loadtxt(fname, dtype=float, comments='#', delimiter=None, converters=None,
              skiprows=0, usecols=None, unpack=False, ndmin=0, encoding=None,
              max_rows=None, *, quotechar=None, like=None)
  1. Import NumPy. import numpy as np
  2. Point to the file. Pass the path as fname. The documentation examples use io.StringIO so they run without a file: from io import StringIO, then c = StringIO("0 1\n2 3").
  3. Call loadtxt. np.loadtxt(c) returns array([[0., 1.], [2., 3.]]). The default delimiter is whitespace, so a comma-separated file needs delimiter=','.
  4. Select columns and unpack. With c = StringIO("1,0,2\n3,0,4"), the call x, y = np.loadtxt(c, delimiter=',', usecols=(0, 2), unpack=True) gives x = array([1., 3.]) and y = array([2., 4.]). Columns are numbered from 0. unpack=True transposes the result so that each column lands in its own variable.
  5. Skip headers. Set skiprows=1 to skip a one-line header. The manual states that skiprows skips the first lines, including comments.
  6. Limit the rows. max_rows reads that many rows of content after the skipped lines. Empty lines and comment lines are not counted towards max_rows.

Output and how to read it

By default the result is a floating-point array: dtype defaults to float. A file with several columns gives a two-dimensional array with one row per line. ndmin accepts 0, 1 or 2 and sets the minimum number of dimensions; with the default of 0, single-valued axes are squeezed away.

For mixed text and numbers, pass a structured dtype. The manual’s example reads “M 21 72” and “F 35 58” with dtype={'names': ('gender', 'age', 'weight'), 'formats': ('S1', 'i4', 'f4')} and returns array([(b'M', 21, 72.), (b'F', 35, 58.)], dtype=[('gender', 'S1'), ('age', '<i4'), ('weight', '<f4')]). With a structured dtype the result is one-dimensional, each row is one record, and the number of columns used must match the number of fields.

Because the result is a NumPy array, it can go straight into plotting code; the CASRAI guide on importing matplotlib.pyplot as plt covers that import, and Python for exploratory data analysis shows where array loading sits in a wider workflow.

Version notes: what changed and when

Several defaults have moved across NumPy releases. The table below is taken from the “Changed in version” notes in the manual.

Argument What the manual says
encoding Default is None, which uses the system default. Before NumPy 2.0 the default was 'bytes' for Python 2 compatibility.
delimiter Only single-character delimiters are supported (changed in 1.23.0). Newline characters cannot be the delimiter.
converters Passing a single callable to apply to all columns was added in 1.23.0.
max_rows From 1.23.0, lines containing no data, including comment lines, are not counted towards max_rows, although they still count in skiprows.
quotechar Quoting support is off by default (quotechar=None); the argument was introduced in 1.23.0.

Quoted fields and converters

If a text field contains the delimiter or the comment character, set quotechar. Inside a quoted item, delimiter and comment characters are ignored, and two consecutive quote characters inside a quoted field mean the first is an escape character. The manual’s example reads '"alpha, #42", 10.0\n"beta, #64", 2.0\n' with dtype=np.dtype([("label", "U12"), ("value", float)]), delimiter="," and quotechar='"'.

The converters argument preprocesses text before parsing. It can be a dictionary mapping column numbers to functions, or, since 1.23.0, a single callable applied to every column. The manual shows {0: lambda x: np.floor(float(x)), 1: lambda x: np.ceil(float(x))} turning “1.618, 2.296” and “3.141, 4.669” into array([[1., 3.], [3., 5.]]), a trailing-minus converter that turns “31.25-” into -31.25, and a converter that parses hexadecimal values with functools.partial(int, base=16) so that “0xDE 0xAD” becomes [222., 173.].

Troubleshooting

  • Rows with different numbers of values. The manual states that each row must have the same number of values to read all of them. If the rows are uneven, a subset of up to n columns, where n is the smallest count of values on any row, can be read by naming columns with usecols. The manual’s example, StringIO("1 2\n2 4\n3 9 12\n4 16 20") with usecols=(0, 1), returns a four-row, two-column array.
  • Delimiter errors. A multi-character delimiter is not supported in current NumPy (single characters only). Re-save the file with a single-character separator or pre-process the lines.
  • Text appearing as bytes or garbled. Set encoding explicitly. The manual notes that encoding='bytes' turns on backward-compatibility workarounds that return byte arrays; override it to receive unicode arrays and pass strings to converters.
  • Header lines or leading metadata. Use skiprows for a fixed number of lines, or leave the default comments='#' to ignore comment-prefixed lines.
  • Missing values. loadtxt is not designed for gaps. Use genfromtxt (next section), and see the CASRAI guide on numpy.nan for how missing values are represented once loaded.

loadtxt vs genfromtxt

The loadtxt manual page says genfromtxt “provides more sophisticated handling of, e.g., lines with missing values”, and the genfromtxt page describes loadtxt as the “equivalent function when no data is missing”. Both pages are sourced below.

Question numpy.loadtxt numpy.genfromtxt
What is it for? A fast reader for simply formatted files Loading text with missing values handled as specified
Name of the leading-lines argument skiprows skip_header (it also has skip_footer)
Missing data Not handled; every row needs the same number of values missing_values sets the strings that mean missing, filling_values sets the defaults to use
Field names Through a structured dtype names=True takes names from the first line after skip_header, or pass a list of names
Row limit max_rows max_rows

The manual’s genfromtxt example reads one line, "1,1.3,abcde", with dtype=None, names=['myint', 'myfloat', 'mystring'] and delimiter=",". The argument name skip_header differs from skiprows, so code cannot be switched between the two functions by changing only the name.

Free alternatives

NumPy and everything listed here are free to use. The “See also” list on the loadtxt manual page names these related functions:

Function Where it is documented
numpy.genfromtxt Text files with missing values; compared in the table above
numpy.load Listed under See also on the loadtxt page
numpy.fromstring Listed under See also on the loadtxt page
numpy.fromregex Listed under See also on the loadtxt page
scipy.io.loadmat Listed under See also on the loadtxt page

For a text format specifically, the CASRAI guide on what a TSV file is explains the tab-separated case, which loadtxt reads with delimiter='\t'.

FAQ

How do I read a CSV file with numpy.loadtxt?

Pass the file name and set delimiter=',', because the default delimiter is whitespace. Add skiprows=1 if the first line is a header.

What is the difference between loadtxt and genfromtxt?

loadtxt is the fast reader for simply formatted files and needs the same number of values on every row. genfromtxt handles missing values through missing_values and filling_values, and it names its header argument skip_header.

How do I load only some columns?

Use usecols with zero-based column numbers, for example usecols=(0, 2). Add unpack=True to receive each column as a separate array.

Does loadtxt handle quoted text containing commas?

Yes, once quoting is turned on with quotechar='"'. Quoting is off by default, and the argument was added in NumPy 1.23.0.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about numpy.loadtxt: Load a Text or CSV File into an Array

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.