Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Pandas›Reading Data: CSV, Excel, JSON, SQL

Getting Started

Reading Data: CSV, Excel, JSON, SQL

This lesson covers the primary entry points for loading external data into memory using efficient parsing engines. Understanding these methods is essential because data ingestion is the foundational step for any analysis pipeline, dictating performance and type inference accuracy. You reach for these functions whenever your raw data needs to be transformed into a structured DataFrame for manipulation, filtering, or statistical modeling.

Loading CSV Files with read_csv

The CSV format is the ubiquitous standard for flat-file data exchange, and read_csv is the workhorse function in your library. When you invoke this function, the engine scans the file to infer column data types based on the content of the first few rows. This process is dynamic, meaning the library assigns types like integer, float, or object based on detected patterns. Understanding this is crucial because incorrect type inference can lead to massive memory overhead; for example, storing strings as objects consumes significantly more space than categorical types. By controlling parameters such as 'dtype', 'sep', and 'usecols', you manually influence the parsing logic to prioritize memory efficiency and speed. Properly defining your column types during the ingestion phase prevents expensive downcasting operations later in your workflow, ensuring that your data structure is optimized for high-performance vectorized operations immediately upon loading.

import pandas as pd

# Loading a dataset with specific types to optimize memory
# usecols allows us to load only the necessary data into memory
df = pd.read_csv('sales_data.csv', 
                 sep=',', 
                 dtype={'id': 'int32', 'revenue': 'float32'},
                 usecols=['id', 'date', 'revenue']) 
print(df.head())

Reading Excel Worksheets

Reading Excel files requires the underlying library to interpret complex spreadsheet metadata such as formatting, merged cells, and multiple sheets. Unlike plain text formats, Excel files carry structural overhead; therefore, read_excel allows you to specify a 'sheet_name' to target specific data segments. A critical aspect of Excel ingestion is that the library must convert rich cell data into a uniform DataFrame structure. If your file contains headers spread across rows or complex formatting, you must utilize the 'header' and 'skiprows' arguments to normalize the input. Because Excel operations are inherently slower than text-based formats, you should be intentional about which ranges you load. Being aware of the internal translation process helps you anticipate common issues like empty row propagation or data type coercion failures when cells contain mixed-type entries, allowing for cleaner initial data structures.

import pandas as pd

# Reading a specific sheet and skipping unnecessary header rows
df = pd.read_excel('financial_report.xlsx', 
                   sheet_name='Q3_Results', 
                   header=1, 
                   skiprows=[2]) # Skip the second row containing comments
print(df.info())

Parsing Semi-Structured JSON

JSON is a semi-structured format that often maps poorly to a flat two-dimensional DataFrame, making read_json a versatile but nuanced tool. Because JSON data can be nested (e.g., objects within objects), the reader often requires an 'orient' parameter to tell it how to map the hierarchy to rows and columns. When you load JSON, the parser recursively traverses the structure, potentially flattening it depending on your configuration. Understanding the 'orient' parameter is vital because choosing the wrong configuration can result in malformed columns or transposed data. If your data is heavily nested, simple reading may not suffice; you might need to use json_normalize to flatten deeply buried attributes. Recognizing that JSON lacks the strict column-row discipline of a CSV file helps you anticipate when you will need to perform post-load transformation to achieve a usable analytical shape.

import pandas as pd

# Reading JSON data where records are organized as a list of dictionaries
# 'records' orientation aligns the JSON structure with the DataFrame format
df = pd.read_json('user_activity.json', orient='records')
print(df.describe())

Querying SQL Databases

Connecting to a database requires a bridge, typically an engine created via a connection string, which the library uses to execute queries and stream results directly into memory. The read_sql function is distinct because it offloads the heavy lifting of data selection and filtering to the database engine itself. This is highly efficient compared to loading an entire table, as you can use SQL syntax to perform aggregations or joins before the data ever hits your local environment. By carefully crafting your SQL SELECT statements, you minimize data transfer and memory footprint. Understanding that this function returns a DataFrame built from a SQL result set is fundamental; you must ensure your query returns a consistent set of columns to maintain predictable types. Always close connections after the data is retrieved to ensure efficient resource management within your environment.

from sqlalchemy import create_engine
import pandas as pd

# Establishing a database connection and executing a selective query
engine = create_engine('sqlite:///company_db.sqlite')
df = pd.read_sql('SELECT id, region, amount FROM transactions WHERE amount > 100', 
                 con=engine)
print(df.shape)

Handling Large Datasets with Chunking

When dealing with files that exceed your available RAM, standard reading functions will cause memory overflow errors. The solution is 'chunking', where you process data in iterative slices rather than loading the entire file at once. By setting the 'chunksize' parameter, the read function returns an iterator of DataFrames. This approach fundamentally changes how you write your code: instead of performing operations on the full dataset, you loop through chunks, applying transformations and aggregations to each subset individually. This allows you to process gigabytes of data on a standard laptop. The reasoning here is simple: you trade off execution time for memory stability. Being adept at chunking is the hallmark of a senior-level practitioner who understands the physical constraints of the local machine and the mechanics of data streaming.

import pandas as pd

# Processing a massive file in chunks of 10,000 rows to save memory
chunk_iterator = pd.read_csv('massive_log_file.csv', chunksize=10000)

for chunk in chunk_iterator:
    # Perform analysis or filtering on each chunk
    print(f'Processing chunk with {len(chunk)} rows')
    # Optionally write the result to a new file incrementally

Key points

  • The read_csv function is the standard tool for flat files and provides parameters to customize column types and memory usage.
  • Excel reading requires careful attention to sheet names and header placement to correctly transform structured cell data.
  • JSON parsing necessitates understanding of data orientation to properly map nested structures into a flat DataFrame format.
  • SQL integration allows the database to perform filtering tasks before transferring data, significantly reducing local memory load.
  • Chunking is a critical technique for processing files that are too large to fit in physical system memory.
  • Specifying data types during ingestion prevents the library from needing to perform costly inference passes on large datasets.
  • Efficient ingestion relies on using parameters like 'usecols' to restrict memory consumption to only the necessary data points.
  • Proper resource management includes closing database connections and using iterators to maintain system stability during data processing.

Common mistakes

  • Mistake: Forgetting to specify the 'index_col' parameter when reading a CSV. Why it's wrong: Pandas creates a default integer index, leading to duplicate indexing issues. Fix: Use 'pd.read_csv('file.csv', index_col=0)' to set the first column as the index.
  • Mistake: Assuming 'pd.read_json()' handles all nested JSON structures perfectly. Why it's wrong: Complex nested dictionaries often need 'pd.json_normalize()' to flatten the data. Fix: Use 'json_normalize' to flatten nested keys into separate columns.
  • Mistake: Relying on default 'read_csv' encoding. Why it's wrong: Files created in Excel often use 'latin1' or 'cp1252' encoding, causing 'UnicodeDecodeError'. Fix: Explicitly set 'encoding='utf-8'' or 'encoding='latin1'' if an error occurs.
  • Mistake: Keeping the entire SQL result set in memory for massive tables. Why it's wrong: It can lead to 'MemoryError' if the database table is too large. Fix: Use the 'chunksize' parameter in 'read_sql' to process data in smaller, manageable segments.
  • Mistake: Trying to read an Excel file with multiple sheets without specifying a sheet name. Why it's wrong: By default, Pandas only imports the first sheet, causing data loss. Fix: Use 'pd.read_excel('file.xlsx', sheet_name='SheetName')' or 'sheet_name=None' to read all sheets into a dictionary.

Interview questions

What is the most fundamental function in Pandas used to load a CSV file, and why is it preferred?

The most fundamental function for loading CSV files in Pandas is 'pd.read_csv()'. It is preferred because it is highly optimized for performance and offers an extensive array of parameters to handle common data issues like missing values, custom delimiters, or specific date formatting during ingestion. By using this function, we can immediately map data types, set index columns, and prune unnecessary rows, ensuring the resulting DataFrame is clean and memory-efficient from the very first moment of loading.

How do you handle reading data from an Excel file, and what specific challenges does this format present compared to CSV?

To read Excel files, we use 'pd.read_excel()'. The primary challenge compared to CSV is that Excel files are binary and often contain multiple sheets, merged cells, or complex formatting that can pollute the data structure. Unlike simple text-based CSVs, Excel files require the 'openpyxl' engine to parse the XML-based structure. We must often specify the 'sheet_name' argument to ensure we are pulling the correct dataset, and we may need to skip header rows if the layout is not strictly tabular.

What approach should be taken when loading nested JSON data into a flat Pandas DataFrame?

When dealing with nested JSON, simply calling 'pd.read_json()' often results in columns containing dictionary objects rather than clean, tabular data. To resolve this, we use the 'pd.json_normalize()' function. This function allows us to flatten nested JSON structures into a tabular format by specifying the path to the data. It is essential because it promotes better performance for vectorized operations, as Pandas functions perform significantly faster on columns containing primitive data types like integers or strings compared to those containing nested Python objects.

How can you query a database directly into a Pandas DataFrame, and why is this approach better than manually exporting to CSV first?

We use 'pd.read_sql()' in conjunction with a database connection object. This approach is far superior to exporting to CSV first because it minimizes I/O overhead and reduces the risk of data corruption or type errors during the export-import process. By pulling directly from the source, we can leverage SQL's power to filter or aggregate the data at the server level, ensuring that only the specific subset needed for analysis is transferred into memory, which is critical for handling large-scale enterprise datasets.

Compare using 'pd.read_csv()' with chunking versus loading the entire file at once. When would you choose one over the other?

Choosing between loading an entire file and using the 'chunksize' parameter depends entirely on available system RAM. If the dataset fits comfortably in memory, loading it at once is simpler and allows for immediate global operations like sorting or merging. However, if the file exceeds memory capacity, 'chunksize' returns an iterator of DataFrames, allowing us to process data in smaller segments. We choose chunking to avoid memory overflow errors, even though it requires more complex logic to accumulate or filter results iteratively.

Explain the significance of the 'dtype' argument when reading large datasets into Pandas and how it impacts performance.

The 'dtype' argument is critical for memory management and performance optimization. By default, Pandas often infers data types, which can be inefficient—for example, assigning a 64-bit float where a 16-bit integer would suffice. By explicitly defining 'dtype' during ingestion, we drastically reduce the memory footprint of the DataFrame. Smaller memory usage allows for faster iteration and prevents memory-swapping, enabling us to process significantly larger datasets that would otherwise crash the environment or result in extremely slow computation times.

All Pandas interview questions →

Check yourself

1. When loading a CSV that uses a semicolon instead of a comma as a separator, which approach ensures the data is parsed correctly?

  • A.Use the sep=';' parameter in read_csv
  • B.Rename the file extension to .tsv
  • C.Set the encoding parameter to 'semicolon'
  • D.Use the delimiter='none' parameter
Show answer

A. Use the sep=';' parameter in read_csv
The 'sep' parameter explicitly defines the character separating the fields. The other options are either irrelevant (renaming extensions) or invalid parameters.

2. A JSON file has a structure where every record is nested under a single key 'employees'. Which method is best to convert this into a flat DataFrame?

  • A.read_json('file.json', orient='index')
  • B.read_json('file.json') and then transpose
  • C.json_normalize(data, record_path='employees')
  • D.read_csv('file.json')
Show answer

C. json_normalize(data, record_path='employees')
json_normalize is designed to flatten nested structures. read_json will not automatically flatten the 'employees' key correctly, and read_csv is not intended for JSON format.

3. When querying a database with 'read_sql', why should you prefer parameterized queries (using 'params') over f-strings for filtering data?

  • A.It makes the code run faster
  • B.It protects against SQL injection attacks
  • C.It is the only way to import datetime objects
  • D.It allows you to read more rows at once
Show answer

B. It protects against SQL injection attacks
Parameterized queries sanitize input to prevent malicious SQL injections. The other options are incorrect, as they do not affect performance or functionality in this way.

4. If you read an Excel file using 'pd.read_excel(file, sheet_name=None)', what is the returned object type?

  • A.A single DataFrame
  • B.A list of column names
  • C.A dictionary of DataFrames
  • D.A Series object containing all sheets
Show answer

C. A dictionary of DataFrames
Setting 'sheet_name=None' instructs Pandas to read all sheets and return them as a dictionary where keys are sheet names and values are DataFrames. The other options describe single objects or incorrect types.

5. What happens if you provide a 'usecols' argument to 'read_csv'?

  • A.Pandas reads only the specified columns, reducing memory usage
  • B.Pandas reads all columns but hides the ones not listed
  • C.Pandas deletes the columns not in the list from the source file
  • D.Pandas generates an error if the columns are not in the first row
Show answer

A. Pandas reads only the specified columns, reducing memory usage
usecols allows for memory-efficient loading by only pulling required data into RAM. The other choices incorrectly describe data manipulation or file-modifying behaviors.

Take the full Pandas quiz →

← PreviousDataFrames — Creation and BasicsNext →Writing and Exporting Data

Pandas

34 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app