Skip to content

BUG: Fix formatters applied to wrong columns in truncated DataFrame.to_string (GH#35410)#65288

Merged
jbrockmendel merged 1 commit intopandas-dev:mainfrom
tinezivic:fix-truncated-formatters
Apr 20, 2026
Merged

BUG: Fix formatters applied to wrong columns in truncated DataFrame.to_string (GH#35410)#65288
jbrockmendel merged 1 commit intopandas-dev:mainfrom
tinezivic:fix-truncated-formatters

Conversation

@tinezivic
Copy link
Copy Markdown
Contributor

@tinezivic tinezivic commented Apr 19, 2026

Bug

DataFrame.to_string() applied formatters dict to wrong columns when output was horizontally truncated via max_cols.

Minimal reproduction:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.arange(30).reshape(5, 6), columns=[f"Col{i}" for i in range(6)])
formatters = {c: (lambda x, c=c: f"{c}: {x}") for c in df.columns}
print(df.to_string(formatters=formatters, max_cols=4))
# Before fix: Col4 shows "Col2: 4", Col5 shows "Col3: 5"
# After fix:  Col4 shows "Col4: 4", Col5 shows "Col5: 5"

Root Cause

In DataFrameFormatter._get_formatter(), when formatters is a dict and i is an integer (positional index), the code resolved i against self.columns (the original frame). After truncation, positional index 2 in the truncated frame corresponds to e.g. Col4, but self.columns[2] returned Col2.

Fix: resolve positional indices against self.tr_frame.columns (the truncated frame) instead of self.columns. Also removed the i not in self.columns guard which caused incorrect behavior when column names are integers.

AI Disclosure

This fix was developed with the assistance of GitHub Copilot (Claude Sonnet 4.6). The AI assisted with code generation and diff review. The contributor verified the fix locally and confirmed the test passes.

@jbrockmendel jbrockmendel merged commit 8d6da16 into pandas-dev:main Apr 20, 2026
45 checks passed
@jbrockmendel
Copy link
Copy Markdown
Member

thanks @tinezivic

Sharl0tteIsTaken added a commit to Sharl0tteIsTaken/pandas that referenced this pull request Apr 22, 2026
…h-origin

* upstream/main: (31 commits)
  DOC:Missing r in your (pandas-dev#65323)
  DOC: fix grammar in the .dt accessor section (pandas-dev#65325)
  REGR: restore rank() for ExtensionArrays with custom values for sorting (pandas-dev#64976)
  BUG: MultiIndex.get_loc returns scalar for unique key in non-unique index (pandas-dev#65234)
  BUG/TST: add test for _cast_pointwise_result robustness + fix some cases (pandas-dev#65318)
  BUG: fix .loc with tuple key on MultiIndex with IntervalIndex level (pandas-dev#65239)
  BUG: permit building from source with mingw (pandas-dev#64849)
  BUG: DataFrame.loc setitem with list-like value on single-column EA DataFrame (pandas-dev#65241)
  PERF: preserve block memory layout in Block.copy (GH#60469) (pandas-dev#65302)
  PERF: short-circuit sort_index(level=...) on monotonic non-MultiIndex (pandas-dev#65279)
  BUG: fix FloatingArray.astype(str) crash with distinguish_nan_and_na=True (pandas-dev#65038)
  BUG: fix to_timedelta ignoring unit for mixed round/non-round floats (pandas-dev#65170)
  BUG: DataFrame.loc preserves original index name when key is an Index (pandas-dev#65229)
  REF: continue moving freq management off DatetimeArray/TimedeltaArray (GH#24566) (pandas-dev#65285)
  REF: remove redundant BaseMaskedArray.map override (pandas-dev#65297)
  Bump github/codeql-action from 4.35.1 to 4.35.2 (pandas-dev#65310)
  Bump actions/setup-node from 6.3.0 to 6.4.0 (pandas-dev#65309)
  BUG: Fix formatters applied to wrong columns in truncated DataFrame.to_string (GH#35410) (pandas-dev#65288)
  PERF: optimize block consolidation (pandas-dev#64574)
  CLN: Replace no_default signature with False for allow_duplicates in insert and reset_index (pandas-dev#65146)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Wrong Custom Formatters applied when displaying trancated frames

2 participants