Repository: pandas-dev/pandas

Issue:
Loss of series name attributes in pd.concat 
`pd.concat` nicely preserves name attributes when given a list of series. However, this only works if all series have the name attribute set, otherwise all names are lost:

```
In [1]: import pandas as pd
In [2]: pd.__version__
Out[2]: '0.16.2'

In [3]: foo = pd.Series([1,2], name='foo')
In [4]: bar = pd.Series([1,2])

In [6]: pd.concat([foo, bar], 1)
Out[6]: 
   0  1
0  1  1
1  2  2
```

Not sure this qualifies as a bug.

Loss of series name attributes in pd.concat 
`pd.concat` nicely preserves name attributes when given a list of series. However, this only works if all series have the name attribute set, otherwise all names are lost:

```
In [1]: import pandas as pd
In [2]: pd.__version__
Out[2]: '0.16.2'

In [3]: foo = pd.Series([1,2], name='foo')
In [4]: bar = pd.Series([1,2])

In [6]: pd.concat([foo, bar], 1)
Out[6]: 
   0  1
0  1  1
1  2  2
```

Not sure this qualifies as a bug.



Discussion:
hmm, so you want

```
In [14]: DataFrame({'foo' : [1,2], 1 : [1,2]},columns=['foo',1])
Out[14]: 
   foo  1
0    1  1
1    2  2
```

seems reasonable. I'll mark it as a bug. pull-requests welcome!

yep, that's it.

gr8. pull-requests welcome!

@jreback Do you have any comment on the last pull request? I fixed all unit tests which were previously failing. 

hmm, so you want

```
In [14]: DataFrame({'foo' : [1,2], 1 : [1,2]},columns=['foo',1])
Out[14]: 
   foo  1
0    1  1
1    2  2
```

seems reasonable. I'll mark it as a bug. pull-requests welcome!

yep, that's it.

gr8. pull-requests welcome!

@jreback Do you have any comment on the last pull request? I fixed all unit tests which were previously failing. 


Resolving patch:
diff --git a/pandas/tools/merge.py b/pandas/tools/merge.py
--- a/pandas/tools/merge.py
+++ b/pandas/tools/merge.py
@@ -3,7 +3,7 @@
 """
 
 import numpy as np
-from pandas.compat import range, long, lrange, lzip, zip, map, filter
+from pandas.compat import range, lrange, lzip, zip, map, filter
 import pandas.compat as compat
 from pandas.core.categorical import Categorical
 from pandas.core.frame import DataFrame, _merge_doc
@@ -15,7 +15,7 @@
 from pandas.core.internals import (items_overlap_with_suffix,
                                    concatenate_block_managers)
 from pandas.util.decorators import Appender, Substitution
-from pandas.core.common import ABCSeries
+from pandas.core.common import ABCSeries, isnull
 
 import pandas.core.common as com
 
@@ -912,8 +912,14 @@ def get_result(self):
                 data = dict(zip(range(len(self.objs)), self.objs))
                 index, columns = self.new_axes
                 tmpdf = DataFrame(data, index=index)
-                if columns is not None:
-                    tmpdf.columns = columns
+                # checks if the column variable already stores valid column names (because set via the 'key' argument
+                # in the 'concat' function call. If that's not the case, use the series names as column names
+                if columns.equals(Index(np.arange(len(self.objs)))) and not self.ignore_index:
+                    columns = np.array([ data[i].name for i in range(len(data)) ], dtype='object')
+                    indexer = isnull(columns)
+                    if indexer.any():
+                        columns[indexer] = np.arange(len(indexer[indexer]))
+                tmpdf.columns = columns
                 return tmpdf.__finalize__(self, method='concat')
 
         # combine block managers


Test patch:
diff --git a/pandas/tools/tests/test_merge.py b/pandas/tools/tests/test_merge.py
--- a/pandas/tools/tests/test_merge.py
+++ b/pandas/tools/tests/test_merge.py
@@ -1879,6 +1879,24 @@ def test_concat_dataframe_keys_bug(self):
         self.assertEqual(list(result.columns), [('t1', 'value'),
                                                 ('t2', 'value')])
 
+    def test_concat_series_partial_columns_names(self):
+        # GH10698
+        foo = pd.Series([1,2], name='foo')
+        bar = pd.Series([1,2])
+        baz = pd.Series([4,5])
+
+        result = pd.concat([foo, bar, baz], axis=1)
+        expected = DataFrame({'foo' : [1,2], 0 : [1,2], 1 : [4,5]}, columns=['foo',0,1])
+        tm.assert_frame_equal(result, expected)
+
+        result = pd.concat([foo, bar, baz], axis=1, keys=['red','blue','yellow'])
+        expected = DataFrame({'red' : [1,2], 'blue' : [1,2], 'yellow' : [4,5]}, columns=['red','blue','yellow'])
+        tm.assert_frame_equal(result, expected)
+
+        result = pd.concat([foo, bar, baz], axis=1, ignore_index=True)
+        expected = DataFrame({0 : [1,2], 1 : [1,2], 2 : [4,5]})
+        tm.assert_frame_equal(result, expected)
+
     def test_concat_dict(self):
         frames = {'foo': DataFrame(np.random.randn(4, 3)),
                   'bar': DataFrame(np.random.randn(4, 3)),
@@ -2412,7 +2430,7 @@ def test_concat_series_axis1(self):
 
         s2.name = None
         result = concat([s, s2], axis=1)
-        self.assertTrue(np.array_equal(result.columns, lrange(2)))
+        self.assertTrue(np.array_equal(result.columns, Index(['A', 0], dtype='object')))
 
         # must reindex, #2603
         s = Series(randn(3), index=['c', 'a', 'b'], name='A')