Repository: pandas-dev/pandas

Issue:
Inappropriate/inconsistent behavior in data assignment (v. 0.13)
I find it convenient to store lists or series as elements in a dataframe. However, it seems panda gets confused if the iterable is the same length as the number of rows in the dataframe. Here's a minimal example:

``` python
matchmat_test = pd.DataFrame(index=[0,1], 
                             columns=[1], dtype=list)
matchmat_test.ix[0,0] = [1,2,3]
```

Returns:

```
           0
0  [1, 2, 3]
1        NaN
```

If we then assign to the same element again:

``` python
matchmat_test.ix[0,0] = [1,2]
```

we get:

```
 0
0  1
1  2
```



Discussion:

Resolving patch:
diff --git a/pandas/core/internals.py b/pandas/core/internals.py
--- a/pandas/core/internals.py
+++ b/pandas/core/internals.py
@@ -605,10 +605,18 @@ def setitem(self, indexer, value):
                                      "different length than the value")
 
         try:
+            # setting a single element for each dim and with a rhs that could be say a list
+            # GH 6043
+            if arr_value.ndim == 1 and (
+                np.isscalar(indexer) or (isinstance(indexer, tuple) and all([ np.isscalar(idx) for idx in indexer ]))):
+                values[indexer] = value
+
             # if we are an exact match (ex-broadcasting),
             # then use the resultant dtype
-            if len(arr_value.shape) and arr_value.shape[0] == values.shape[0] and np.prod(arr_value.shape) == np.prod(values.shape):
+            elif len(arr_value.shape) and arr_value.shape[0] == values.shape[0] and np.prod(arr_value.shape) == np.prod(values.shape):
                 values = arr_value.reshape(values.shape)
+
+            # set
             else:
                 values[indexer] = value
 


Test patch:
diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py
--- a/pandas/tests/test_indexing.py
+++ b/pandas/tests/test_indexing.py
@@ -1286,6 +1286,48 @@ def test_ix_get_set_consistency(self):
         self.assert_(df.ix['e', 8] == 45)
         self.assert_(df.loc['e', 8] == 45)
 
+    def test_setitem_list(self):
+
+        # GH 6043
+        # ix with a list
+        df = DataFrame(index=[0,1], columns=[0])
+        df.ix[1,0] = [1,2,3]
+        df.ix[1,0] = [1,2]
+
+        result = DataFrame(index=[0,1], columns=[0])
+        result.ix[1,0] = [1,2]
+
+        assert_frame_equal(result,df)
+
+        # ix with an object
+        class TO(object):
+            def __init__(self, value):
+                self.value = value
+            def __str__(self):
+                return "[{0}]".format(self.value)
+            __repr__ = __str__
+            def __eq__(self, other):
+                return self.value == other.value
+            def view(self):
+                return self
+
+        df = DataFrame(index=[0,1], columns=[0])
+        df.ix[1,0] = TO(1)
+        df.ix[1,0] = TO(2)
+
+        result = DataFrame(index=[0,1], columns=[0])
+        result.ix[1,0] = TO(2)
+
+        assert_frame_equal(result,df)
+
+        # remains object dtype even after setting it back
+        df = DataFrame(index=[0,1], columns=[0])
+        df.ix[1,0] = TO(1)
+        df.ix[1,0] = np.nan
+        result = DataFrame(index=[0,1], columns=[0])
+
+        assert_frame_equal(result, df)
+
     def test_iloc_mask(self):
 
         # GH 3631, iloc with a mask (of a series) should raise