Repository: pandas-dev/pandas

Issue:
BUG: DataFrame.explode doesn't explode when using pyarrow large list type
### Pandas version checks

- [x] I have checked that this issue has not already been reported.

- [x] I have confirmed this bug exists on the [latest version](https://pandas.pydata.org/docs/whatsnew/index.html) of pandas.

- [x] I have confirmed this bug exists on the [main branch](https://pandas.pydata.org/docs/dev/getting_started/install.html#installing-the-development-version-of-pandas) of pandas.


### Reproducible Example

```python
In [4]: pd.DataFrame({'a': [[1, 2], [3, 4]]}, dtype=pd.ArrowDtype(pa.list_(pa.int64()))).explode('a')
Out[4]:
   a
0  1
0  2
1  3
1  4

In [5]: pd.DataFrame({'a': [[1, 2], [3, 4]]}, dtype=pd.ArrowDtype(pa.large_list(pa.int64()))).explode('a')
Out[5]:
       a
0  [1 2]
1  [3 4]
```

### Issue Description

For `list_`, it explodes correctly, but for `large_list`, it's a no-op

### Expected Behavior

```
   a
0  1
0  2
1  3
1  4
```

### Installed Versions

<details>

INSTALLED VERSIONS
------------------
commit                : 57fd50221ea3d5de63d909e168f10ad9fc0eee9b
python                : 3.10.12
python-bits           : 64
OS                    : Linux
OS-release            : 5.15.167.4-microsoft-standard-WSL2
Version               : #1 SMP Tue Nov 5 00:21:55 UTC 2024
machine               : x86_64
processor             : x86_64
byteorder             : little
LC_ALL                : None
LANG                  : C.UTF-8
LOCALE                : en_US.UTF-8

pandas                : 3.0.0.dev0+1979.g57fd50221e
numpy                 : 1.26.4
dateutil              : 2.9.0.post0
pip                   : 25.0.1
Cython                : 3.0.12
sphinx                : 8.1.3
IPython               : 8.33.0
adbc-driver-postgresql: None
adbc-driver-sqlite    : None
bs4                   : 4.13.3
blosc                 : None
bottleneck            : 1.4.2
fastparquet           : 2024.11.0
fsspec                : 2025.2.0
html5lib              : 1.1
hypothesis            : 6.127.5
gcsfs                 : 2025.2.0
jinja2                : 3.1.5
lxml.etree            : 5.3.1
matplotlib            : 3.10.1
numba                 : 0.61.0
numexpr               : 2.10.2
odfpy                 : None
openpyxl              : 3.1.5
psycopg2              : 2.9.10
pymysql               : 1.4.6
pyarrow               : 19.0.1
pyreadstat            : 1.2.8
pytest                : 8.3.5
python-calamine       : None
pytz                  : 2025.1
pyxlsb                : 1.0.10
s3fs                  : 2025.2.0
scipy                 : 1.15.2
sqlalchemy            : 2.0.38
tables                : 3.10.1
tabulate              : 0.9.0
xarray                : 2024.9.0
xlrd                  : 2.0.1
xlsxwriter            : 3.2.2
zstandard             : 0.23.0
tzdata                : 2025.1
qtpy                  : None
pyqt5                 : None

</details>


Discussion:

Fix (patch):
diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst
index 25c26253e6..5581bac2b2 100644
--- a/doc/source/whatsnew/v3.0.0.rst
+++ b/doc/source/whatsnew/v3.0.0.rst
@@ -782,6 +782,7 @@ Reshaping
 ^^^^^^^^^
 - Bug in :func:`qcut` where values at the quantile boundaries could be incorrectly assigned (:issue:`59355`)
 - Bug in :meth:`DataFrame.combine_first` not preserving the column order (:issue:`60427`)
+- Bug in :meth:`DataFrame.explode` producing incorrect result for :class:`pyarrow.large_list` type (:issue:`61091`)
 - Bug in :meth:`DataFrame.join` inconsistently setting result index name (:issue:`55815`)
 - Bug in :meth:`DataFrame.join` when a :class:`DataFrame` with a :class:`MultiIndex` would raise an ``AssertionError`` when :attr:`MultiIndex.names` contained ``None``. (:issue:`58721`)
 - Bug in :meth:`DataFrame.merge` where merging on a column containing only ``NaN`` values resulted in an out-of-bounds array access (:issue:`59421`)
diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py
index e2feda495c..9295cf7873 100644
--- a/pandas/core/arrays/arrow/array.py
+++ b/pandas/core/arrays/arrow/array.py
@@ -1938,7 +1938,10 @@ class ArrowExtensionArray(
         """
         # child class explode method supports only list types; return
         # default implementation for non list types.
-        if not pa.types.is_list(self.dtype.pyarrow_dtype):
+        if not (
+            pa.types.is_list(self.dtype.pyarrow_dtype)
+            or pa.types.is_large_list(self.dtype.pyarrow_dtype)
+        ):
             return super()._explode()
         values = self
         counts = pa.compute.list_value_length(values._pa_array)


Test changes:
diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py
index 15d615fc35..e4ad2493f9 100644
--- a/pandas/tests/series/methods/test_explode.py
+++ b/pandas/tests/series/methods/test_explode.py
@@ -145,8 +145,9 @@ def test_explode_scalars_can_ignore_index():
 
 
 @pytest.mark.parametrize("ignore_index", [True, False])
-def test_explode_pyarrow_list_type(ignore_index):
-    # GH 53602
+@pytest.mark.parametrize("list_type", ["list_", "large_list"])
+def test_explode_pyarrow_list_type(ignore_index, list_type):
+    # GH 53602, 61091
     pa = pytest.importorskip("pyarrow")
 
     data = [
@@ -156,7 +157,7 @@ def test_explode_pyarrow_list_type(ignore_index):
         [2, 3],
         None,
     ]
-    ser = pd.Series(data, dtype=pd.ArrowDtype(pa.list_(pa.int64())))
+    ser = pd.Series(data, dtype=pd.ArrowDtype(getattr(pa, list_type)(pa.int64())))
     result = ser.explode(ignore_index=ignore_index)
     expected = pd.Series(
         data=[None, None, 1, None, 2, 3, None],