Package: clevercsv
CleverCSV provides a drop-in replacement for the Pythoncsvpackage
with improved dialect detection for messy CSV files. It also provides a handy
command line tool that can standardize a messy file or generate Python code to
import it.Useful links:CleverCSV on GithubCleverCSV on PyPIDocumentation on ReadTheDocsDemo of CleverCSV on Binder (interactive!)Research Paper on CSV dialect detection
(PDF)Reproducible Research RepoBlog post on messy CSV filesDiscussion
forum: a
place to ask questions and share ideas!Contents:Quick Start|Introduction|Installation|Usage|Python Library|Command-Line Tool|Version Control Integration|Contributing|NotesQuick StartClick hereto go to the introduction with more details about
CleverCSV. If you're in a hurry, below is a quick overview of how to get
started with the CleverCSV Python package and the command line interface.For the Python package:# Import the package>>>importclevercsv# Load the file as a list of rows# This uses the imdb.csv file in the examples directory>>>rows=clevercsv.read_table('./imdb.csv')# Load the file as a Pandas Dataframe# Note that df = pd.read_csv('./imdb.csv') would fail here>>>df=clevercsv.read_dataframe('./imdb.csv')# Use CleverCSV as drop-in replacement for the Python CSV module# This follows the Sniffer example: https://docs.python.org/3/library/csv.html#csv.Sniffer# Note that csv.Sniffer would fail here>>>withopen('./imdb.csv',newline='')ascsvfile:...dialect=clevercsv.Sniffer().sniff(csvfile.read())...csvfile.seek(0)...reader=clevercsv.reader(csvfile,dialect)...rows=list(reader)And for the command line interface:# Install the full version of CleverCSV (this includes the command line interface)$pipinstallclevercsv[full]# Detect the dialect$clevercsvdetect./imdb.csvDetected:SimpleDialect(',','','\\')# Generate code to import the file$clevercsvcode./imdb.csvimportclevercsvwithopen("./imdb.csv","r",newline="",encoding="utf-8")asfp:reader=clevercsv.reader(fp,delimiter=",",quotechar="",escapechar="\\")rows=list(reader)# Explore the CSV file as a Pandas dataframe$clevercsvexplore-pimdb.csvDroppingyouintoaninteractiveshell.CleverCSVhasloadedthedataintothevariable:df>>>dfIntroductionCSV files are awesome! They are lightweight, easy to share, human-readable,
version-controllable, and supported by many systems and tools!CSV files are terrible! They can have many different formats, multiple
tables, headers or no headers, escape characters, and there's no support for
recording metadata!CleverCSV is a Python package that aims to solve some of the pain points of
CSV files, while maintaining many of the good things. The package
automatically detects (with high accuracy) the format (dialect) of CSV
files, thus making it easier to simply point to a CSV file and load it,
without the need for human inspection. In the future, we hope to solve some of
the other issues of CSV files too.CleverCSV isbased on
science.
We investigated thousands of real-world CSV files to find a robust way to
automatically detect the dialect of a file. This may seem like an easy
problem, but to a computer a CSV file is simply a long string, and every
dialect will give yousometable. In CleverCSV we use a technique based on
the patterns of row lengths of the parsed file and the data type of the
resulting cells. With our method we achieve 97% accuracy for dialect
detection, with a 21% improvement on non-standard (messy) CSV files compared
to the Python standard library.We think this kind of work can be very valuable for working data scientists
and programmers and we hope that you find CleverCSV useful (if there's a
problem, please open an issue!) Since the academic world counts citations,
pleasecite CleverCSV if you use the package. Here's a BibTeX entry you
can use:@article{van2019wrangling,title={Wrangling Messy {CSV} Files by Detecting Row and Type Patterns},author={{van den Burg}, G. J. J. and Naz{\'a}bal, A. and Sutton, C.},journal={Data Mining and Knowledge Discovery},year={2019},volume={33},number={6},pages={1799--1820},issn={1573-756X},doi={10.1007/s10618-019-00646-y},}And of course, if you like the package pleasespread the word!You can do
this by Tweeting about it
(#CleverCSV) or clicking the ⭐️on
GitHub!InstallationCleverCSV is available on PyPI. You can install either the full version, which
includes the command line interface and all optional dependencies, using$pipinstallclevercsv[full]or you can install a lighter, core version of CleverCSV with$pipinstallclevercsvUsageCleverCSV consists of a Python library and a command line tool calledclevercsv.Python LibraryWe designed CleverCSV to provide a drop-in replacement for the built-in CSV
module, with some useful functionality added to it. Therefore, if you simply
want to replace the builtin CSV module with CleverCSV, you can import
CleverCSV as follows, and use it as you would use the builtincsv
module.importclevercsvCleverCSV provides an improved version of the dialect sniffer in the CSV
module, but it also adds some useful wrapper functions. These functions
automatically detect the dialect and aim to make working with CSV files
easier. We currently have the following helper functions:detect_dialect:
takes a path to a CSV file and returns the detected dialectread_table:
automatically detects the dialect and encoding of the file, and returns the
data as a list of rows. A version that returns a generator is also
available:stream_tableread_dataframe:
detects the dialect and encoding of the file and then usesPandasto read the CSV into a DataFrame. Note
that this function requires Pandas to be installed.read_dicts:
detect the dialect and return the rows of the file as dictionaries, assuming
the first row contains the headers. A streaming version calledstream_dictsis also available.write_table:
write a table (a list of lists) to a file using theRFC-4180dialect.write_dicts:
write a list of dictionaries to a file using theRFC-4180dialect.Of course, you can also use the traditional way of loading a CSV file, as in
the Python CSV module:importclevercsvwithopen("data.csv","r",newline="")asfp:# you can use verbose=True to see what CleverCSV doesdialect=clevercsv.Sniffer().sniff(fp.read(),verbose=False)fp.seek(0)reader=clevercsv.reader(fp,dialect)rows=list(reader)Since CleverCSV v0.8.0, dialect detection is a lot faster than in previous
versions. However, forlarge files, you can speed up detection even more
by supplying a sample of the document to the sniffer instead of the whole
file, for example:dialect=clevercsv.Sniffer().sniff(fp.read(10000))You can also speed up encoding detection by installingcCharDet, it will automatically be used
when it is available on the system.That's the basics! If you want more details, you can look at the code of the
package, the test suite, or theAPI
documentation.
If you run into any issues or have comments or suggestions, please open an
issueon GitHub.Command-Line ToolTo use the command line tool, make sure that you install the full version of
CleverCSV (see above).Theclevercsvcommand line application has a number of handy features to
make working with CSV files easier. For instance, it can be used to view a CSV
file on the command line while automatically detecting the dialect. It can
also generate Python code for importing data from a file with the correct
dialect. The full help text is as follows:usage: clevercsv [-h] [-V] [-v] command ...

Available commands:
  help         Display help information
  detect       Detect the dialect of a CSV file
  view         View the CSV file on the command line using TabView
  standardize  Convert a CSV file to one that conforms to RFC-4180
  code         Generate Python code to import a CSV file
  explore      Explore the CSV file in an interactive Python shellEach of the commands has further options (for instance, thecodeandexplorecommands have support for importing the CSV file as a Pandas
DataFrame). Useclevercsv help <command>orman clevercsv <command>for more information. Below are some examples for each command.Note that each command accepts the-nor--num-charsflag to set the
number of characters used to detect the dialect. This can be especially
helpful to speed up dialect detection on large files.CodeCode generation is useful when you don't want to detect the dialect of the
same file over and over again. You simply run the following command and copy
the generated code to a Python script!$ clevercsv code imdb.csv

# Code generated with CleverCSV

import clevercsv

with open("imdb.csv", "r", newline="", encoding="utf-8") as fp:
    reader = clevercsv.reader(fp, delimiter=",", quotechar="", escapechar="\\")
    rows = list(reader)We also have a version that reads a Pandas dataframe:$ clevercsv code --pandas imdb.csv

# Code generated with CleverCSV

import clevercsv

df = clevercsv.read_dataframe("imdb.csv", delimiter=",", quotechar="", escapechar="\\")DetectDetection is useful when you only want to know the dialect.$ clevercsv detect imdb.csv
Detected: SimpleDialect(',', '', '\\')The--plainflag gives the components of the dialect on separate lines,
which makes combining it withgrepeasier.$ clevercsv detect --plain imdb.csv
delimiter = ,
quotechar =
escapechar = \ExploreTheexplorecommand is great for a command-line based workflow, or when
you quickly want to start working with a CSV file in Python. This command
detects the dialect of a CSV file and starts an interactive Python shell with
the file already loaded! You can either have the file loaded as a list of
lists:$ clevercsv explore milk.csv
Dropping you into an interactive shell.

CleverCSV has loaded the data into the variable: rows
>>>
>>> len(rows)
381or you can load the file as a Pandas dataframe:$ clevercsv explore -p imdb.csv
Dropping you into an interactive shell.

CleverCSV has loaded the data into the variable: df
>>>
>>> df.head()
                   fn        tid  ... War Western
0  titles01/tt0012349  tt0012349  ...   0       0
1  titles01/tt0015864  tt0015864  ...   0       0
2  titles01/tt0017136  tt0017136  ...   0       0
3  titles01/tt0017925  tt0017925  ...   0       0
4  titles01/tt0021749  tt0021749  ...   0       0

[5 rows x 44 columns]StandardizeUse thestandardizecommand when you want to rewrite a file using theRFC-4180 standard:$ clevercsv standardize --output imdb_standard.csv imdb.csvIn this particular example the use of the escape character is replaced by
using quotes.ViewThis command allows you to view the file in the terminal. The dialect is of
course detected using CleverCSV! Both this command and thestandardizecommand support the--transposeflag, if you want to transpose the file
before viewing or saving:$ clevercsv view --transpose imdb.csvVersion Control IntegrationIf you'd like to make sure that you never commit a messy (non-standard) CSV
file to your repository, you can install apre-commithook. First, install pre-commit using
theinstallation instructions. Next, add
the following configuration to the.pre-commit-config.yamlfile in your
repository:repos:-repo:https://github.com/alan-turing-institute/CleverCSV-pre-commitrev:v0.6.6# or any later versionhooks:-id:clevercsv-standardizeFinally, runpre-commit installto set up the git hook. Pre-commit will
now use CleverCSV to standardize your CSV files followingRFC-4180whenever you commit a CSV file
to your repository.ContributingIf you want to encourage development of CleverCSV, the best thing to do now is
tospread the word!If you encounter an issue in CleverCSV, pleaseopen an
issueorsubmit a pull
request.
Don't hesitate, you're helping to make this project better for everyone! If
GitHub's not your thing but you still want to contact us, you can send an
email togertjanvandenburg at gmail dot cominstead. You can also ask
questionson Gitter.Note that all contributions to the project must adhere to theCode of
Conduct.The CleverCSV package was originally written byGertjan van den
Burgand came out ofscientific
researchon wrangling messy CSV files byGertjan van den Burg,Alfredo Nazabal, andCharles Sutton.NotesCleverCSV is licensed under theMIT license. Pleasecite our
researchif you
use CleverCSV in your work.Copyright (c) 2018-2021The Alan Turing Institute.