---
title: "Python in Excel: When a Cell Stops Being a Number and Becomes a DataFrame"
date: 2026-06-29T00:00:00Z
updated: 2026-06-27T11:15:25Z
tags: ["Python", "Excel", "Microsoft 365", "Dynamic Arrays"]
canonical: https://bianca.codes/blog/python-in-excel-cell-becomes-a-dataframe/
---

# Python in Excel: When a Cell Stops Being a Number and Becomes a DataFrame

_For forty years an Excel cell could hold one of four things, and Python in Excel quietly added a fifth: a whole pandas DataFrame, living inside a single cell._

For about forty years, an Excel cell could hold exactly one of four things: a number, some text, a TRUE or FALSE, or an error. That was the whole list. Every formula you have ever written resolves down to one of those four primitives landing in one cell. The entire grid is built on that constraint, and most of what makes Excel feel like Excel comes from it.

Python in Excel quietly broke the list. Type `=PY()` into a cell, run `df.groupby(...)`, and the thing sitting in that cell is now a pandas DataFrame. Not a number that summarises the DataFrame. The DataFrame. An entire table, with its columns and dtypes and index intact, living at a single grid coordinate. That is a stranger and more important change than "you can write Python now," and it is the part worth slowing down for.

## The mental model

Here is the shift. A normal formula returns a value, and the value is the cell. `=SUM(A1:A10)` puts a number in the cell, and that number is all the cell is. There is nothing else in there.

A `=PY()` formula returns an object, and the cell holds a reference to it. When your Python code ends on a DataFrame, the cell points at that DataFrame as a live object sitting in the Python runtime. Excel shows it as a card with a little table icon, because there is no single number to display - what is in the cell is not a value, it is a thing that has values. The same is true if your code returns a Series, a fitted scikit-learn model, or a matplotlib figure. The cell became a handle on an object.

This is why every `=PY()` cell has a switch that normal cells do not: it can be shown as a **Python object** or as an **Excel value**. As a Python object, the cell stays a reference to the DataFrame, and you can pass it into other Python cells whole. As an Excel value, Excel reaches into the object and spills its contents out across the grid as ordinary numbers and text, which is the form `=SUM` and `=VLOOKUP` and a chart can actually read. The toggle is the entire concept made operable: you are choosing, per cell, whether you want the object or the picture of the object.

So the mental move is to stop thinking "this formula produces a value" and start thinking "this cell holds an object, and I decide when to turn it back into values." Once a DataFrame can live in a cell, the cell stops being the end of the calculation and becomes a place you store intermediate work, the same way you store an intermediate variable in a script.

## The syntax

You enter a Python cell by typing `=PY(` into it, at which point the cell flips into Python mode and the formula bar grows a green PY badge. From there you are writing Python, not Excel.

Grid data comes in through one function, `xl()`, which is the bridge from the worksheet to Python:

```python
xl("A1:D500", headers=True)   # a range, as a DataFrame with a header row
xl("Sales[Amount]")            # one table column, as a Series
xl("B2")                       # a single cell, as a scalar
```

`xl()` is the only thing that reaches back out to the grid. Everything else is normal Python. The cell returns whatever its last expression evaluates to:

```python
df = xl("Sales[#All]", headers=True)
df.groupby("Region")["Amount"].sum()
```

That cell now holds a Series of regional totals. Leave it as a Python object and it is a card you can feed into the next cell. Switch it to an Excel value and the totals spill down the sheet like any dynamic array. `pandas` is already imported as `pd` and `numpy` as `np`, so there is no setup cell to run first - the runtime starts with the usual suspects loaded.

## A real example

A monthly sales export lands in a table called `Sales`: Region, Channel, Date, Amount, a few thousand rows. The job is the usual one, total by region and channel, but watch where the intermediate results live.

First Python cell, in say F1:

```python
df = xl("Sales[#All]", headers=True)
summary = df.groupby(["Region", "Channel"])["Amount"].sum().reset_index()
summary
```

That cell holds `summary` as a Python object - the grouped DataFrame, shown as a card. Nothing has spilled yet. The whole result is sitting in one cell, F1, as an object.

Now a second Python cell, below it in F2, that does more work on the same object:

```python
summary.sort_values("Amount", ascending=False).head(10)
```

It uses `summary` directly, by name, with no `xl()` call to fetch it back. That works because Python cells on a sheet share one namespace, and a variable defined in an earlier cell is visible to a later one. The DataFrame you built in F1 is still a live object when F2 runs, so F2 keeps working on it. This is the bit that feels like a script and not a spreadsheet: F1 is a variable assignment, F2 is the next line of the program.

Only at the end, when you want a person to read it, do you flip the final cell to **Excel value** and let the top ten spill into the grid as a normal table that a chart or a `=SUM` can sit on top of. The objects did the work in the middle; the grid gets the answer at the end.

## Where it bites

It runs in the cloud, not on your machine. Every `=PY()` cell sends your data to a Microsoft-hosted container, runs the code there, and sends the result back. The practical consequences are real: you cannot open a local file path, the runtime has no access to your `C:` drive, and a heavy recalculation has network latency a normal formula never does. Python in Excel is not a local Python install wearing an Excel hat.

Calculation order is not what you are used to. Normal Excel works out a dependency graph and calculates in whatever order the dependencies require. Python cells do not. They run top to bottom, left to right across the sheet, in reading order, and a cell can only see variables defined in cells above it or to its left. Define `summary` below the cell that uses it and you get a `NameError`, even though in classic Excel the position would not matter at all. The order on the page is the order of execution.

You cannot install packages. The library set is the Anaconda distribution Microsoft ships, which is generous - `pandas`, `numpy`, `matplotlib`, `seaborn`, `statsmodels`, `scikit-learn`, and plenty more - but it is fixed. There is no `pip install` for the one niche package your problem wants. If it is not in the distribution, it is not available.

And a Python object cell is opaque to ordinary formulas. `=SUM()` pointed at a cell holding a DataFrame does not reach inside it and add the numbers up - it sees an object it does not understand. Anything in the grid that needs the values needs the cell materialised to an Excel value first, or the aggregation done in Python and only the result handed back. The object and the grid are two worlds, and `xl()` going in and the Excel-value toggle coming out are the only doors between them.

## Where this fits

This is the inverse of the [Python for Excel Users series](/blog/python-for-excel-users-part-1-reading-and-filtering-your-first-real-dataset/), which spent four parts teaching pandas as the thing you reach for when you want to leave the grid behind. Python in Excel brings the same pandas back inside the grid, which changes the calculus of when leaving is worth it. For the full build, wiring `=PY()` into a real monthly report that pulls a table, groups it, and charts the result without a single cell leaving Excel, see the [Jun 30 Build It](/blog/build-monthly-report-card-python-in-excel/). And for the ninety-second version, the one `=PY()` cell that replaces your most-rebuilt pivot table, there is the [Click Bait](#).

## Frequently Asked Questions

### **Does Python in Excel run on my computer?**

No. It runs in a secure Microsoft-hosted container in the cloud, built on Azure Container Instances with packages from Anaconda. Your worksheet data is sent there, the code executes remotely, and the result comes back to the cell. That is why there is no local Python to install, why the runtime cannot see your local files, and why a big calculation carries some network latency.

### **Which versions and plans have it?**

It is a Microsoft 365 feature, available on Excel for Windows and Excel for the web. It reached general availability on Windows in late 2024 and on the web in early 2025, and eligibility later expanded to more subscription tiers including Office 365 E1, Business Basic, and F3. Standard compute is included with a qualifying subscription; faster premium compute and manual recalculation are a paid add-on.

### **Can I install my own Python libraries?**

No. You get the fixed set of packages in the Anaconda distribution Microsoft ships, which includes pandas, numpy, matplotlib, seaborn, statsmodels, and scikit-learn among many others. There is no pip install, so if your problem needs a package that is not in the distribution, Python in Excel cannot do it and the work belongs in a real Python environment.

### **Why does my Python cell throw a NameError when the variable is defined right there?**

Because the definition is below or to the right of the cell using it. Python cells calculate in reading order, top to bottom and left to right, and a cell can only see variables from cells that come before it in that order. Move the definition above or to the left of where it is used. This is the single most common surprise for people who expect Excel's order-independent recalculation.

### **How do I get a DataFrame back into normal cells?**

Switch the cell's output from Python object to Excel value, using the toggle in the formula bar. As a Python object the cell stays a reference and shows as a card; as an Excel value Excel spills the contents into the grid as ordinary numbers and text, which is the form regular formulas and charts can read. You can also do the final aggregation in Python and return a small result directly.

### **Does it work on Mac or the mobile apps?**

No. Python in Excel is Windows and web only. Because the Python runtime is a hosted container rather than something running on the device, the Mac desktop app and the mobile apps do not support it. A workbook with `=PY()` cells will open on those platforms, but the Python cells will not recalculate there.
