Behavior of slugify and renaming of duplicate columns seems inconsistent
See test `test_rename_slugify_columns_in_place`

Not sure what to do about this. Should probably revisit what happens to dupe column names.

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 96356ae..7155799 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,7 @@
 1.5.6
 -----
-
+* Reimplemented slugify with python-slugify instead of awesome-slugify. (#660)
+* Slugify renaming of duplicate values is now consistent with :meth:`.Table.init`. (#615)
 
 
 1.5.5 - December 29, 2016
diff --git a/agate/table/__init__.py b/agate/table/__init__.py
index b214351..150d9ee 100644
--- a/agate/table/__init__.py
+++ b/agate/table/__init__.py
@@ -82,30 +82,7 @@ class Table(object):
 
         # Validate column names
         if column_names:
-            final_column_names = []
-
-            for i, column_name in enumerate(column_names):
-                if not column_name:
-                    new_column_name = utils.letter_name(i)
-                    warn_unnamed_column(i, new_column_name)
-                elif isinstance(column_name, six.string_types):
-                    new_column_name = column_name
-                else:
-                    raise ValueError('Column names must be strings or None.')
-
-                final_column_name = new_column_name
-                duplicates = 0
-
-                while final_column_name in final_column_names:
-                    final_column_name = new_column_name + '_' + str(duplicates + 2)
-                    duplicates += 1
-
-                if duplicates > 0:
-                    warn_duplicate_column(new_column_name, final_column_name)
-
-                final_column_names.append(final_column_name)
-
-            self._column_names = tuple(final_column_names)
+            self._column_names = utils.deduplicate(column_names, column_names=True)
         elif rows:
             self._column_names = tuple(utils.letter_name(i) for i in range(len(rows[0])))
             warnings.warn('Column names not specified. "%s" will be used as names.' % str(self._column_names), RuntimeWarning, stacklevel=2)
diff --git a/agate/table/rename.py b/agate/table/rename.py
index 27ee135..8f35719 100644
--- a/agate/table/rename.py
+++ b/agate/table/rename.py
@@ -42,7 +42,10 @@ def rename(self, column_names=None, row_names=None, slug_columns=False, slug_row
         column_names = column_names or self._column_names
 
         if column_names is not None:
-            column_names = utils.slugify(column_names, ensure_unique=True, **kwargs)
+            if column_names == self._column_names:
+                column_names = utils.slugify(column_names, ensure_unique=False, **kwargs)
+            else:
+                column_names = utils.slugify(column_names, ensure_unique=True, **kwargs)
 
     if slug_rows:
         row_names = row_names or self.row_names
diff --git a/agate/utils.py b/agate/utils.py
index 7b5954c..4d5e2ef 100644
--- a/agate/utils.py
+++ b/agate/utils.py
@@ -10,7 +10,8 @@ from collections import OrderedDict, Sequence
 from functools import wraps
 import string
 import warnings
-from slugify import Slugify, UniqueSlugify
+from slugify import slugify as pslugify
+from agate.warns import warn_duplicate_column, warn_unnamed_column
 
 try:
     from cdecimal import Decimal, ROUND_FLOOR, ROUND_CEILING, getcontext
@@ -252,22 +253,65 @@ def issequence(obj):
     return isinstance(obj, Sequence) and not isinstance(obj, six.string_types)
 
 
+def deduplicate(values, column_names=False, separator='_'):
+    """
+    Append a unique identifer to duplicate strings in a given sequence of
+    strings. Identifers are an underscore followed by the occurance number of
+    the specific string.
+
+    ['abc', 'abc', 'cde', 'abc'] -> ['abc', 'abc_2', 'cde', 'abc_3']
+
+    :param column_names:
+        If True, values are treated as column names. Warnings will be thrown
+        if column names are None or duplicates. None values will be replaced with
+        letter indices.
+    """
+    final_values = []
+
+    for i, value in enumerate(values):
+        if column_names:
+            if not value:
+                new_value = letter_name(i)
+                warn_unnamed_column(i, new_value)
+            elif isinstance(value, six.string_types):
+                new_value = value
+            else:
+                raise ValueError('Column names must be strings or None.')
+        else:
+            new_value = value
+
+        final_value = new_value
+        duplicates = 0
+
+        while final_value in final_values:
+            final_value = new_value + separator + str(duplicates + 2)
+            duplicates += 1
+
+        if column_names and duplicates > 0:
+            warn_duplicate_column(new_value, final_value)
+
+        final_values.append(final_value)
+
+    return tuple(final_values)
+
+
 def slugify(values, ensure_unique=False, **kwargs):
     """
     Given a sequence of strings, returns a standardized version of the sequence.
     If ``ensure_unique`` is True, any duplicate strings will be appended with
-    a unique identifier. Any kwargs will be passed to the Slugify or
-    UniqueSlugify class constructor
+    a unique identifier.
+
+    agate uses an underscore as a default separator but this can be changed with
+    kwargs.
 
-    See: https://github.com/dimka665/awesome-slugify
+    Any kwargs will be passed to the slugify method in python-slugify. See:
+    https://github.com/un33k/python-slugify
     """
-    # Default to all lowercase
-    slug_args = {'to_lower': True}
+    slug_args = {'separator': '_'}
     slug_args.update(kwargs)
 
     if ensure_unique:
-        custom_slugify = UniqueSlugify(**slug_args)
+        new_values = tuple(pslugify(value, **slug_args) for value in values)
+        return deduplicate(new_values, separator=slug_args['separator'])
     else:
-        custom_slugify = Slugify(**slug_args)
-
-    return tuple(custom_slugify(value) for value in values)
+        return tuple(pslugify(value, **slug_args) for value in values)
diff --git a/requirements-py2.txt b/requirements-py2.txt
index 25d738c..d36d7ca 100644
--- a/requirements-py2.txt
+++ b/requirements-py2.txt
@@ -12,7 +12,7 @@ parsedatetime>=2.1
 pytz>=2015.4
 mock>=1.3.0
 isodate>=0.5.4
-awesome-slugify>=1.6.5
+python-slugify>=1.2.1
 lxml>=3.6.0
 cssselect>=0.9.1
 leather>=0.3.2
diff --git a/requirements-py3.txt b/requirements-py3.txt
index ecf3d1e..d1e9bd4 100644
--- a/requirements-py3.txt
+++ b/requirements-py3.txt
@@ -10,7 +10,7 @@ Babel>=2.0
 parsedatetime>=2.1
 pytz>=2015.4
 isodate>=0.5.4
-awesome-slugify>=1.6.5
+python-slugify>=1.2.1
 lxml>=3.6.0
 cssselect>=0.9.1
 leather>=0.3.2
diff --git a/setup.py b/setup.py
index 8064529..0c52c74 100644
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@ install_requires = [
     'parsedatetime>=2.1',
     'Babel>=2.0',
     'isodate>=0.5.4',
-    'awesome-slugify>=1.6.5',
+    'python-slugify>=1.2.1',
     'leather>=0.3.2'
 ]
 
diff --git a/tests/test_computations.py b/tests/test_computations.py
index 8a7752b..b8c118a 100644
--- a/tests/test_computations.py
+++ b/tests/test_computations.py
@@ -370,7 +370,7 @@ class TestTableComputation(unittest.TestCase):
             ('Ab*c #e', 2),
             ('He11O W0rld', 3)
         )
-        expected = ['hello-world', 'ab-c-e', 'he11o-w0rld']
+        expected = ['hello_world', 'ab_c_e', 'he11o_w0rld']
 
         table = Table(rows, ['one', 'two'], [self.text_type, self.number_type]).compute([
             ('slugs', Slug('one'))
@@ -384,7 +384,7 @@ class TestTableComputation(unittest.TestCase):
             ('Ab*c #e', 2, 'He11O W0rld'),
             ('He11O W0rld', 3, 'hello world')
         )
-        expected = ['hello-world-ab-c-e', 'ab-c-e-he11o-w0rld', 'he11o-w0rld-hello-world']
+        expected = ['hello_world_ab_c_e', 'ab_c_e_he11o_w0rld', 'he11o_w0rld_hello_world']
 
         table1 = Table(rows, ['one', 'two', 'three'], [self.text_type, self.number_type, self.text_type])
         table2 = table1.compute([
@@ -400,7 +400,7 @@ class TestTableComputation(unittest.TestCase):
             ('He11O W0rld', 3),
             ('HellO WOrld ', 3)
         )
-        expected = ['hello-world', 'ab-c-e', 'he11o-w0rld', 'hello-world-1']
+        expected = ['hello_world', 'ab_c_e', 'he11o_w0rld', 'hello_world_2']
 
         table = Table(rows, ['one', 'two'], [self.text_type, self.number_type]).compute([
             ('slugs', Slug('one', ensure_unique=True))
diff --git a/tests/test_table/test_rename.py b/tests/test_table/test_rename.py
index 2f9f540..859d91e 100644
--- a/tests/test_table/test_rename.py
+++ b/tests/test_table/test_rename.py
@@ -78,8 +78,8 @@ class TestRename(AgateTestCase):
         table3 = table.rename(strings, slug_columns=True, separator='.')
 
         self.assertColumnNames(table, ['one', 'two', 'three'])
-        self.assertColumnNames(table2, ['test-koz', 'test-2', 'test-2-1'])
-        self.assertColumnNames(table3, ['test.koz', 'test.2', 'test.2.1'])
+        self.assertColumnNames(table2, ['test_koz', 'test_2', 'test_2_2'])
+        self.assertColumnNames(table3, ['test.koz', 'test.2', 'test.2.2'])
 
     def test_rename_slugify_rows(self):
         strings = ['Test kož', 'test 2', 'test 2']
@@ -89,8 +89,8 @@ class TestRename(AgateTestCase):
         table3 = table.rename(row_names=strings, slug_rows=True, separator='.')
 
         self.assertIs(table.row_names, None)
-        self.assertRowNames(table2, ['test-koz', 'test-2', 'test-2-1'])
-        self.assertRowNames(table3, ['test.koz', 'test.2', 'test.2.1'])
+        self.assertRowNames(table2, ['test_koz', 'test_2', 'test_2_2'])
+        self.assertRowNames(table3, ['test.koz', 'test.2', 'test.2.2'])
 
     def test_rename_slugify_columns_in_place(self):
         column_names = [u'Test kož', 'test 2', 'test 2']
@@ -106,7 +106,7 @@ class TestRename(AgateTestCase):
         table3 = table.rename(slug_columns=True, separator='.')
 
         self.assertColumnNames(table, [u'Test kož', 'test 2', 'test 2_2'])
-        self.assertColumnNames(table2, ['test-koz', 'test-2', 'test-2-2'])
+        self.assertColumnNames(table2, ['test_koz', 'test_2', 'test_2_2'])
         self.assertColumnNames(table3, ['test.koz', 'test.2', 'test.2.2'])
 
     def test_rename_slugify_rows_in_place(self):
@@ -117,5 +117,5 @@ class TestRename(AgateTestCase):
         table3 = table.rename(slug_rows=True, separator='.')
 
         self.assertRowNames(table, ['Test kož', 'test 2', 'test 2'])
-        self.assertRowNames(table2, ['test-koz', 'test-2', 'test-2-1'])
-        self.assertRowNames(table3, ['test.koz', 'test.2', 'test.2.1'])
+        self.assertRowNames(table2, ['test_koz', 'test_2', 'test_2_2'])
+        self.assertRowNames(table3, ['test.koz', 'test.2', 'test.2.2'])
['agate/table/__init__.py', 'requirements-py2.txt', 'setup.py', 'tests/test_computations.py', 'agate/table/rename.py', 'agate/utils.py', 'CHANGELOG.rst', 'tests/test_table/test_rename.py', 'requirements-py3.txt']