diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt
index 2a2e08c2ccf5d..cb906374840c4 100644
--- a/doc/source/whatsnew/v0.21.0.txt
+++ b/doc/source/whatsnew/v0.21.0.txt
@@ -81,6 +81,7 @@ Other Enhancements
- :func:`date_range` now accepts 'YS' in addition to 'AS' as an alias for start of year (:issue:`9313`)
- :func:`date_range` now accepts 'Y' in addition to 'A' as an alias for end of year (:issue:`9313`)
- Integration with `Apache Parquet `__, including a new top-level :func:`read_parquet` and :func:`DataFrame.to_parquet` method, see :ref:`here `.
+- :func:`DataFrame.add_prefix` and :func:`DataFrame.add_suffix` now accept strings containing the '%' character. (:issue:`17151`)
.. _whatsnew_0210.api_breaking:
diff --git a/pandas/core/internals.py b/pandas/core/internals.py
index 25c367fcbd968..37fc1c01061ec 100644
--- a/pandas/core/internals.py
+++ b/pandas/core/internals.py
@@ -5,6 +5,7 @@
import operator
from datetime import datetime, timedelta, date
from collections import defaultdict
+from functools import partial
import numpy as np
@@ -2959,11 +2960,11 @@ def rename_axis(self, mapper, axis, copy=True, level=None):
return obj
def add_prefix(self, prefix):
- f = (str(prefix) + '%s').__mod__
+ f = partial('{prefix}{}'.format, prefix=prefix)
return self.rename_axis(f, axis=0)
def add_suffix(self, suffix):
- f = ('%s' + str(suffix)).__mod__
+ f = partial('{}{suffix}'.format, suffix=suffix)
return self.rename_axis(f, axis=0)
@property
diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py
index f63918c97c614..8c4c13b66ffa9 100644
--- a/pandas/tests/frame/test_api.py
+++ b/pandas/tests/frame/test_api.py
@@ -68,6 +68,14 @@ def test_add_prefix_suffix(self):
expected = pd.Index(['%s#foo' % c for c in self.frame.columns])
tm.assert_index_equal(with_suffix.columns, expected)
+ with_pct_prefix = self.frame.add_prefix('%')
+ expected = pd.Index(['%{}'.format(c) for c in self.frame.columns])
+ tm.assert_index_equal(with_pct_prefix.columns, expected)
+
+ with_pct_suffix = self.frame.add_suffix('%')
+ expected = pd.Index(['{}%'.format(c) for c in self.frame.columns])
+ tm.assert_index_equal(with_pct_suffix.columns, expected)
+
class TestDataFrameMisc(SharedWithSparse, TestData):