Reading and writing CSV/TSV files with Python
CSV and TSV formats are essentially text files formatted in a specific way: the former one separates data using a comma and the latter uses tab \t
characters. Thanks to this, they are really portable and facilitate the ease of sharing data between various platforms.
Getting ready
To execute this recipe, you will need the pandas
module installed. These modules are all available in the Anaconda distribution of Python and no further work is required if you already use this distribution. Otherwise, you will need to install pandas
and make sure that it loads properly.
Note
You can download Anaconda from http://docs.continuum.io/anaconda/install. If you already have Python installed but do not have pandas
, you can download the package from https://github.com/pydata/pandas/releases/tag/v0.17.1 and follow the instructions to install it appropriately for your operating system (http://pandas.pydata.org/pandas-docs/stable/install.html).
No other prerequisites are required.
How to do it…
The
pandas
module is a library that provides high-performing, high-level data structures (such as DataFrame) and some basic analytics tools for Python.
Note
The DataFrame is an Excel table-like data structure where each column represents a feature of your dataset (for example, the height and weight of people) and each row holds the data (for example, 1,000 random people's heights and weights). See http://pandas.pydata.org/pandas-docs/stable/dsintro.html#dataframe.
The module provides methods that make it very easy to read data stored in a variety of formats. Here's a snippet of a code that reads the data from CSV and TSV formats, stores it in a pandas
DataFrame structure, and then writes it back to the disk (the read_csv.py
file):
import pandas as pd # names of files to read from r_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv' r_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv' # names of files to write to w_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv' w_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv' # read the data csv_read = pd.read_csv(r_filenameCSV) tsv_read = pd.read_csv(r_filenameTSV, sep='\t') # print the first 10 records print(csv_read.head(10)) print(tsv_read.head(10)) # write to files with open(w_filenameCSV,'w') as write_csv: write_csv.write(tsv_read.to_csv(sep=',', index=False)) with open(w_filenameTSV,'w') as write_tsv: write_tsv.write(csv_read.to_csv(sep='\t', index=False))
Now, open the command-line console (on Windows, you can use either command line or Cygwin and in the Linux/Mac environment, you go to Terminal) and execute the following command:
python read_csv.py
You shall see an output similar to the following (abbreviated):
Baths beds city latitude longitude price \ 0 1 2 SACRAMENTO 38.631913 -121.434879 59222 1 1 3 SACRAMENTO 38.478902 -121.431028 68212 2 1 2 SACRAMENTO 38.618305 -121.443839 68880 ...
Tip
Downloading the example code
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
You can download the code files by following these steps:
- Log in or register to our website using your e-mail address and password.
- Hover the mouse pointer on the SUPPORT tab at the top.
- Click on Code Downloads & Errata.
- Enter the name of the book in the Search box.
- Select the book for which you're looking to download the code files.
- Choose from the drop-down menu where you purchased this book from.
- Click on Code Download.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
- WinRAR / 7-Zip for Windows
- Zipeg / iZip / UnRarX for Mac
- 7-Zip / PeaZip for Linux
How it works…
First, we load pandas
to get access to the DataFrame and all its methods that we will use to read and write the data. Note that we alias the pandas
module using as
and specifying the name, pd
; we do this so that later in the code we do not need to write the full name of the package when we want to access DataFrame or the read_csv(...)
method. We store the filenames (for the reading and writing) in r_filenameCSV(TSV)
and w_filenameCSV(TSV)
respectively.
To read the data, we use pandas'
read_csv(...)
method. The method is very universal and accepts a variety of input parameters. However, at a minimum, the only required parameter is either the filename of the file or a buffer that is, an opened file object. In order to read the realEstate_trans.tsv
file, you might want to specify the sep='\t'
parameter; by default, read_csv(...)
will try to infer the separator but I do not like to leave it to chance and always specify the separator explicitly.
As the two files hold exactly the same data, you can check whether the files were read properly by printing out some records. This can be accomplished using the .head(<no_of_rows>)
method invoked on the DataFrame object, where <no_of_rows>
specifies how many rows to print out.
Storing the data in pandas'
DataFrame object means that it really does not matter what format the data was initially in; once read, it can then be saved in any format supported by pandas
. In the preceding example, we write the contents read from a CSV file to a file in a TSV format.
The with open(...) as ...:
structure should always be used to open files for either reading or writing. The advantage of opening files in this way is that it closes the file properly once you are done with reading from or writing to even if, for some reason, an exception occurs during the process.
Note
An exception is a situation that the programmer did not expect to see when he or she wrote the program.
Consider, for example, that you have a file where each line contains only one number: you open the file and start reading from it. As each line of the file is treated as text when read, you need to transform the read text into an integer—a data structure that a computer understands (and treats) as a number, not a text.
All is fine if your data really contains only numbers. However, as you will learn later in this chapter, all data that we gather is dirty in some way, so if, for instance, any of the rows contains a letter instead of a number, the transformation will fail and Python will raise an exception.
The open(<filename>, 'w')
command opens the file specified by <filename>
to write (the w
parameter). Also, you can open files in read mode by specifying 'r'
instead. If you open a file in the 'r+'
mode, Python will allow a bi-directional flow of data (read and write) so you will be able to append contents at the end of the file if needed. You can also specify rb
or wb
for binary type of data (not text).
The .to_csv(...)
method converts the content of a DataFrame to a format ready to store in a text file. You need to specify the separator, for example, sep=','
, and whether the DataFrame index is to be stored in the file as well; by default, the index is also stored. As we do not want that, you should specify index=False
.
Note
The DataFrame's index is essentially an easy way to identify, align, and access your data in the DataFrame. The index can be a consecutive list of numbers (just like row numbers in Excel) or dates; you can even specify two or more index columns. The index column is not part of your data (even though it is printed to screen when you print the DataFrame object). You can read more about indexing at http://pandas.pydata.org/pandas-docs/stable/indexing.html.
There's more…
Described here is the easiest and quickest way of reading data from and writing data to CSV and TSV files. If you prefer to hold your data in a data structure other than pandas
' DataFrame, you can use the csv
module. You then read the data as follows (the read_csv_alternative.py
file):
import csv # names of files to read from r_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv' r_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv' # data structures to hold the data csv_labels = [] tsv_labels = [] csv_data = [] tsv_data = [] # read the data with open(r_filenameCSV, 'r') as csv_in: csv_reader = csv.reader(csv_in) # read the first line that holds column labels csv_labels = csv_reader.__next__() # iterate through all the records for record in csv_reader: csv_data.append(record) with open(r_filenameTSV, 'r') as tsv_in: tsv_reader = csv.reader(tsv_in, delimiter='\t') tsv_labels = tsv_reader.__next__() for record in tsv_reader: tsv_data.append(record) # print the labels print(csv_labels, '\n') print(tsv_labels, '\n') # print the first 10 records print(csv_data[0:10],'\n') print(tsv_data[0:10],'\n')
We store the labels and data in separate lists, csv(tsv)_labels
and csv(tsv)_data
respectively. The .reader(...)
method reads the data from the specified file line by line. To create a .reader(...)
object, you need to pass an open CSV or TSV file object. In addition, if you want to read a TSV file, you need to specify the delimiter as well, just like DataFrame.
Tip
The csv
module also provides the csv.writer
object that allows saving data in a CSV/TSV format. See the documentation of the csv
module at https://docs.python.org/3/library/csv.html.
See also
Check the pandas
documentation for read_csv(...)
and write_csv(...)
to learn more about the plethora of parameters these methods accept. The documentation can be found at http://pandas.pydata.org/pandas-docs/stable/io.html#io-read-csv-table.