How to print a dataframe in Python

Your guide to printing DataFrames in Python. Learn various methods, tips, real-world applications, and how to debug common errors.

How to print a dataframe in Python
Published on: 
Fri
Feb 20, 2026
Updated on: 
Mon
Apr 6, 2026
The Replit Team

You can print a pandas DataFrame for data analysis and debugging in Python. This task lets you inspect your data structure, verify transformations, and present results clearly.

In this article, we'll cover several techniques to display your data effectively. You'll find practical tips, see real-world applications, and get debugging advice for common display issues.

Using print() to display a dataframe

import pandas as pd
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35]}
df = pd.DataFrame(data)
print(df)--OUTPUT--Name Age
0 Alice 25
1 Bob 30
2 Charlie 35

The most direct way to view your DataFrame is with Python's built-in print() function. The code first creates a dictionary and converts it into a pandas DataFrame called df. This establishes a basic two-dimensional data structure with labeled axes, which is the standard format for tabular data in pandas. If you're new to DataFrames, start by understanding creating a pandas DataFrame from various data sources.

When you use print(df), pandas automatically formats the output into a clean, readable table. This includes the index, column headers, and all the data, giving you a quick and clear snapshot of your dataset's structure and contents.

Standard display methods

While print() is great for a quick look, pandas offers more refined methods for inspecting specific parts of your data or customizing the entire output.

Using head() and tail() to view portions of data

import pandas as pd
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'], 'Age': [25, 30, 35, 40, 45]}
df = pd.DataFrame(data)
print(df.head(2)) # First 2 rows
print(df.tail(2)) # Last 2 rows--OUTPUT--Name Age
0 Alice 25
1 Bob 30
Name Age
3 David 40
4 Eve 45

When you're working with large datasets, printing the entire DataFrame is often impractical. The head() and tail() methods offer a more efficient way to inspect your data. They let you preview a small section of the DataFrame, which is perfect for a quick check.

  • head(n): Displays the first n rows. If you don't specify a number, it defaults to the first 5 rows.
  • tail(n): Shows the last n rows. It also defaults to the last 5 rows if n is omitted.

This approach helps you quickly verify data loading and transformations without overwhelming your screen in a memory-efficient way.

Selecting specific rows and columns

import pandas as pd
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35], 'City': ['New York', 'Boston', 'Chicago']}
df = pd.DataFrame(data)
print(df[['Name', 'City']]) # Select specific columns
print(df.iloc[1:3]) # Select rows by position--OUTPUT--Name City
0 Alice New York
1 Bob Boston
2 Charlie Chicago
Name Age City
1 Bob 30 Boston
2 Charlie 35 Chicago

You can also zero in on specific data. To display only certain columns, pass their names as a list inside double brackets, like df[['Name', 'City']]. This is great for focusing on relevant fields.

  • For selecting rows, iloc lets you use integer positions. The expression df.iloc[1:3] grabs the rows at index 1 and 2, since the slice stops before the last number.

These techniques offer precise control for data inspection.

Setting display options with set_option()

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(3, 8), columns=list('ABCDEFGH'))
pd.set_option('display.max_columns', 4)
pd.set_option('display.width', 40)
print(df)--OUTPUT--A B ... G H
0 -0.321875 -0.576953 ... -0.535644 0.990838
1 -1.624340 -0.481165 ... 0.635323 0.156805
2 0.159715 0.902301 ... 0.663896 -0.207663

[3 rows x 8 columns]

You can fine-tune how pandas displays your data using the pd.set_option() function. This is perfect for managing large DataFrames that would otherwise clutter your screen. It changes the display settings for your entire session or script.

In the example, two key options are adjusted:

  • display.max_columns is set to 4, telling pandas to show only four columns and represent the hidden ones with an ellipsis.
  • display.width limits the output's character width, forcing it to wrap or abbreviate to fit the specified space.

Advanced formatting techniques

While global settings are useful, you can get even more granular control with advanced methods like to_string(), sample(), and techniques for managing float precision.

Customizing string output with to_string()

import pandas as pd
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Score': [85, 92, 78]}
df = pd.DataFrame(data)
print(df.to_string(index=False, justify='left'))--OUTPUT--Name Score
Alice 85
Bob 92
Charlie 78

The to_string() method gives you precise control over your DataFrame's string representation, going beyond a standard print(). You can pass arguments to customize the output for a cleaner presentation. In the example, two key parameters are used to adjust the final look.

  • index=False: This removes the default row index. It’s useful when the index numbers don't add meaningful information to your data.
  • justify='left': This argument left-aligns the column content, ensuring a tidy and uniform appearance.

This approach is perfect for preparing data for reports or logs where formatting is key.

Controlling float precision in output

import pandas as pd
import numpy as np
data = {'Value': [np.pi, np.e, 1/3, np.sqrt(2)]}
df = pd.DataFrame(data)
with pd.option_context('display.precision', 2):
print(df)--OUTPUT--Value
0 3.14
1 2.72
2 0.33
3 1.41

When your DataFrame contains floating-point numbers, you might want to control their precision for a cleaner look. The pd.option_context() manager is perfect for this. It lets you temporarily change display settings only for a specific block of code, so you don't alter your global configuration.

  • In this example, 'display.precision' is set to 2.
  • This tells pandas to round all float outputs to two decimal places.

Once the with block finishes, the display settings automatically revert to their original state. It's a great way to apply formatting locally.

Working with large dataframes using sample()

import pandas as pd
import numpy as np
large_df = pd.DataFrame(np.random.randn(1000, 3), columns=['A', 'B', 'C'])
print(large_df.sample(3, random_state=42))--OUTPUT--A B C
798 -0.449513 1.822226 0.573092
543 0.112573 -0.408078 0.693705
151 -1.011989 -0.357691 -0.063096

When head() and tail() don't provide a representative view of your data, the sample() method is a great alternative. It pulls a random selection of rows from anywhere in your DataFrame. This can give you a better sense of the data's overall distribution, especially in large datasets where specialized techniques for handling large datasets become essential.

  • The argument 3 tells pandas to select three random rows.
  • Using random_state=42 makes your results reproducible. Every time you run the code, you'll get the exact same "random" sample, which is great for consistent testing and debugging.

Move faster with Replit

Replit is an AI-powered development platform that comes with all Python dependencies pre-installed, so you can skip setup and start coding instantly. This environment helps you move from learning individual techniques to building complete applications with tools like Agent 4.

Instead of piecing together functions, you can describe the app you want to build and let the Agent take it from idea to working product. For example, you could create:

  • A data cleanup utility that uses to_string() to format a DataFrame into a clean, index-free list for log files.
  • A dashboard widget that displays a preview of a large dataset using head() and tail() to quickly verify its contents.
  • A financial summary tool that selects specific columns and formats currency values to two decimal places for a clean report.

Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.

Common errors and challenges

Even with the right tools, you might hit display issues like truncation or messy formatting, but these are simple to fix.

When your DataFrame is large, pandas truncates the output with ellipses (...) to keep it tidy. To see all your data, you can adjust the display settings. Use pd.set_option('display.max_rows', None) and pd.set_option('display.max_columns', None) to remove the limits and force pandas to print the entire DataFrame.

You'll often find NaN (Not a Number) values in your data, which represent missing information. While accurate, they aren't always ideal for presentation. You can make your output clearer by replacing them before printing using the fillna() method, which swaps every NaN value with a custom string like 'N/A'.

DataFrames with a MultiIndex, or hierarchical index, can also be tricky to display because the nested levels can look cluttered. For a simpler, flat table view, you can use reset_index(). This method converts the index levels into regular columns, making the structure much more straightforward for quick analysis or reporting.

Fixing truncated dataframe display with set_option()

If your DataFrame is too wide, pandas will hide the middle columns with an ellipsis (...) to save space. This truncation can be frustrating when you need to see everything at once. Take a look at the code below for an example.

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.rand(5, 15))
print(df) # Will show truncated output with ...

The code creates a DataFrame with 15 columns, which is more than pandas displays by default, resulting in a truncated output. Check the next example to see how you can force a complete display of all columns.

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.rand(5, 15))
pd.set_option('display.max_columns', 15)
pd.set_option('display.width', 1000)
print(df) # Shows all columns

To fix the truncated view, you can adjust pandas' display settings. The solution uses pd.set_option() to expand the visible area, which is helpful when you need a complete overview of your dataset.

  • 'display.max_columns' is set to 15 to match the DataFrame's column count.
  • 'display.width' is increased to 1000 to give the output enough space to prevent wrapping.

This ensures all your data is visible without any hidden columns.

Handling NaN values in dataframe display

Missing data, represented as NaN values, can clutter your output. While you might try to isolate these values for inspection using isna(), this approach can return confusing results. For a cleaner approach, consider removing NaN values entirely from your dataset. The code below demonstrates this common pitfall, producing an unexpected output.

import pandas as pd
import numpy as np

data = {'Name': ['Alice', 'Bob', 'Charlie'],
'Score': [85, np.nan, 78]}
df = pd.DataFrame(data)
print(df[df.isna()]) # Returns empty DataFrame

The expression df[df.isna()] doesn't filter rows as you might expect. Instead, it applies a mask that replaces valid data with NaN, which is why the output is not useful. See the correct approach below.

import pandas as pd
import numpy as np

data = {'Name': ['Alice', 'Bob', 'Charlie'],
'Score': [85, np.nan, 78]}
df = pd.DataFrame(data)
print(df[df['Score'].isna()]) # Correctly shows row with NaN

The correct approach is to apply the filter to a specific column. The expression df[df['Score'].isna()] works because it isolates the check to the Score column, which is the standard method for conditional filtering.

  • First, df['Score'].isna() creates a boolean Series that is True for rows with NaN.
  • The DataFrame then uses this Series as a mask to select and show only those specific rows.

Correctly displaying MultiIndex dataframes

When you're working with a MultiIndex DataFrame, the default print output isn't always clear. The nested index levels often lack context, making the data hard to read. Check out the example below to see what this looks like in practice.

import pandas as pd

idx = pd.MultiIndex.from_product([['A', 'B'], [1, 2]])
df = pd.DataFrame({'Value': [10, 20, 30, 40]}, index=idx)
print(df) # Confusing output without level names

The output is ambiguous because the MultiIndex levels are unnamed. You can't tell what the index values represent, which obscures the data's structure. The following example shows how to add the necessary clarity.

import pandas as pd

idx = pd.MultiIndex.from_product([['A', 'B'], [1, 2]],
names=['Group', 'ID'])
df = pd.DataFrame({'Value': [10, 20, 30, 40]}, index=idx)
print(df) # Clear hierarchical structure

To fix the confusing output, you can name your index levels. By passing a list of strings to the names parameter in pd.MultiIndex.from_product(), you add context to each level. In this case, names=['Group', 'ID'] labels the hierarchy, making the DataFrame's structure immediately clear.

This simple step transforms a confusing table into a readable one. It's a good practice whenever you're creating hierarchical indexes to ensure your data is easy to interpret.

Real-world applications

Beyond just viewing data, these formatting techniques let you create custom reports and export polished tables for real-world use.

Creating custom summary reports with describe()

The describe() method quickly generates a statistical summary of your numerical data, making it an excellent starting point for creating custom reports.

import pandas as pd
import numpy as np

sales_data = {'Product': ['A', 'B', 'C', 'D'],
'Units': [150, 200, 75, 125],
'Price': [10.99, 24.50, 5.99, 15.75]}
df = pd.DataFrame(sales_data)
summary = df.describe().round(2)
print(summary)

This code first organizes sales data into a DataFrame. The key action happens when describe() is called, which automatically calculates several statistics for the numerical columns—Units and Price. This type of rapid data exploration is perfect for vibe coding workflows, especially when working with real datasets from reading CSV files.

  • It computes the count, mean, and standard deviation.
  • It also finds the minimum, maximum, and quartile values.

The round(2) method is then chained to the result. This cleans up the output by rounding all the calculated numbers to two decimal places. It's a great way to present financial data clearly.

Exporting styled DataFrames to HTML

You can also export a DataFrame directly to an HTML table using the to_html() method, which is perfect for preserving conditional formatting in reports or web pages.

import pandas as pd
import numpy as np

# Create sales performance data
data = {'Salesperson': ['Alice', 'Bob', 'Charlie', 'David'],
'Target': [100, 100, 100, 100],
'Actual': [120, 85, 110, 95]}
df = pd.DataFrame(data)

# Apply styling based on performance
styled_df = df.style.highlight_max(color='lightgreen', axis=0, subset=['Actual'])
styled_df = styled_df.highlight_min(color='lightpink', axis=0, subset=['Actual'])

# Export to HTML (showing just the HTML string here)
html = styled_df.to_html()
print(f"HTML output length: {len(html)} characters")

This code shows how you can apply conditional styling directly to a pandas DataFrame before exporting it. It uses the .style accessor, which allows you to chain different formatting rules together to create a visually rich table. With AI-powered Python development, tasks like this become even more accessible.

  • The highlight_max() method finds the highest value in the Actual column and colors its cell light green.
  • Similarly, highlight_min() targets the lowest value and colors it light pink.

Finally, the to_html() method converts the styled DataFrame into an HTML string, embedding the color formatting directly into the table's code. For different output formats, you might also want to learn about saving DataFrames to CSV for data sharing and storage.

Get started with Replit

Now, turn these techniques into a real tool. Just tell Replit Agent what to build, like "a script that exports a styled HTML table from a CSV" or "a utility that summarizes API data with clean formatting."

The Agent writes the code, tests for errors, and deploys your app right from your browser. Start building with Replit.

Build your first app today

Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.

Build your first app today

Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.