Repository: pandas-dev/pandas

Issue:
BUG: pd.concat with all Series on axis=1 ignores the `names` argument.
#### Code Sample, a copy-pastable example if possible

```python
# Example 1
s = pd.Series([1, 2, 3])
df = pd.concat([s, s], axis=1, keys=['a', 'b'], names=['Test'])
df.columns.names  # this gives back FrozenList([None]) instead of FrozenList(['Test'])
    
# Example 2
df = pd.concat([s, s], axis=1, keys=[('a', 1), ('b', 2)], names=['Test1', 'Test2'])
df.columns.names  # this gives back FrozenList([None, None]) instead of FrozenList(['Test1', 'Test2'])

```
#### Problem description

This is a problem because the API allows a user to provide a names argument with these input types and rather than throw an error or take the argument into consideration it is ignored. As far as I can tell, there is no reason for the names argument to be ignored, considering the keys are applied correctly, so I believe this was just an oversight in the `core.reshape.concat._Concatenator._get_concat_axis` method.

#### Proposed Solution

On line 503 of pandas/core/reshape/concat.py the following line:
`return ensure_index(self.keys)`
Should be replaced with something along these lines:

    new_axis = ensure_index(self.keys)
    new_axis.names = self.names
    return new_axis

This solution solves provides the desired output for both examples above and does not break any of the test_concat.py tests.


#### Output of ``pd.show_versions()``
pandas: 0.24.0.dev0



Discussion:
@ArtinSarraf : Good catch!  Feel free to submit your patch as a PR!

Resolving patch:
diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py
--- a/pandas/core/reshape/concat.py
+++ b/pandas/core/reshape/concat.py
@@ -500,7 +500,7 @@ def _get_concat_axis(self):
                 else:
                     return ibase.default_index(len(self.objs))
             else:
-                return ensure_index(self.keys)
+                return ensure_index(self.keys).set_names(self.names)
         else:
             indexes = [x._data.axes[self.axis] for x in self.objs]
 


Test patch:
diff --git a/pandas/tests/reshape/test_concat.py b/pandas/tests/reshape/test_concat.py
--- a/pandas/tests/reshape/test_concat.py
+++ b/pandas/tests/reshape/test_concat.py
@@ -1618,6 +1618,23 @@ def test_concat_series_axis1(self, sort=sort):
         expected = DataFrame({'A': s, 'B': s2})
         assert_frame_equal(result, expected)
 
+    def test_concat_series_axis1_names_applied(self):
+        # ensure names argument is not ignored on axis=1, #23490
+        s = Series([1, 2, 3])
+        s2 = Series([4, 5, 6])
+        result = concat([s, s2], axis=1, keys=['a', 'b'], names=['A'])
+        expected = DataFrame([[1, 4], [2, 5], [3, 6]],
+                             columns=pd.Index(['a', 'b'], name='A'))
+        assert_frame_equal(result, expected)
+
+        result = concat([s, s2], axis=1, keys=[('a', 1), ('b', 2)],
+                        names=['A', 'B'])
+        expected = DataFrame([[1, 4], [2, 5], [3, 6]],
+                             columns=MultiIndex.from_tuples([('a', 1),
+                                                             ('b', 2)],
+                                                            names=['A', 'B']))
+        assert_frame_equal(result, expected)
+
     def test_concat_single_with_key(self):
         df = DataFrame(np.random.randn(10, 4))