Repository: pandas-dev/pandas

Issue:
Dictionary assignment with loc with existing index doesn't properly match column names in dict
uses the example DataFrame from #9857.

``` python
In [3]: df = pd.DataFrame({'x': [1,2,6], 'y': [2,2,8], 'z':[-5,0,5]})

In [4]: df = df.set_index('z')

In [5]: rhs = {'x': 9, 'y': 99}

In [6]: df.loc[5]
Out[6]:
x    6
y    8
Name: 5, dtype: int64

In [7]: df.loc[5] = rhs

In [8]: df
Out[8]:
                      x                    y
z
-5                    1                    2
 0                    2                    2
 5  {u'y': 99, u'x': 9}  {u'y': 99, u'x': 9}
```



Discussion:
I didn't realize that we supported dictionaries on the RHS of assignments :)

this does an `.append(...)` with the stuff on the rhs.

Is this documented somewhere?


Resolving patch:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -4414,12 +4414,12 @@ def mode(self, axis=0, numeric_only=False):
         """
         Gets the mode(s) of each element along the axis selected. Empty if nothing
         has 2+ occurrences. Adds a row for each mode per label, fills in gaps
-        with nan. 
-        
+        with nan.
+
         Note that there could be multiple values returned for the selected
-        axis (when more than one item share the maximum frequency), which is the 
-        reason why a dataframe is returned. If you want to impute missing values 
-        with the mode in a dataframe ``df``, you can just do this: 
+        axis (when more than one item share the maximum frequency), which is the
+        reason why a dataframe is returned. If you want to impute missing values
+        with the mode in a dataframe ``df``, you can just do this:
         ``df.fillna(df.mode().iloc[0])``
 
         Parameters
diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py
--- a/pandas/core/indexing.py
+++ b/pandas/core/indexing.py
@@ -200,7 +200,6 @@ def _has_valid_positional_setitem_indexer(self, indexer):
         return True
 
     def _setitem_with_indexer(self, indexer, value):
-
         self._has_valid_setitem_indexer(indexer)
 
         # also has the side effect of consolidating in-place
@@ -486,8 +485,8 @@ def can_do_equal_len():
                     self.obj[item_labels[indexer[info_axis]]] = value
                     return
 
-            if isinstance(value, ABCSeries):
-                value = self._align_series(indexer, value)
+            if isinstance(value, (ABCSeries, dict)):
+                value = self._align_series(indexer, Series(value))
 
             elif isinstance(value, ABCDataFrame):
                 value = self._align_frame(indexer, value)


Test patch:
diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py
--- a/pandas/tests/test_frame.py
+++ b/pandas/tests/test_frame.py
@@ -5970,18 +5970,18 @@ def test_boolean_comparison(self):
 
     def test_equals_different_blocks(self):
         # GH 9330
-        df0 = pd.DataFrame({"A": ["x","y"], "B": [1,2], 
+        df0 = pd.DataFrame({"A": ["x","y"], "B": [1,2],
                             "C": ["w","z"]})
         df1 = df0.reset_index()[["A","B","C"]]
-        # this assert verifies that the above operations have 
+        # this assert verifies that the above operations have
         # induced a block rearrangement
-        self.assertTrue(df0._data.blocks[0].dtype != 
+        self.assertTrue(df0._data.blocks[0].dtype !=
                         df1._data.blocks[0].dtype)
         # do the real tests
         self.assert_frame_equal(df0, df1)
         self.assertTrue(df0.equals(df1))
         self.assertTrue(df1.equals(df0))
-        
+
     def test_to_csv_from_csv(self):
 
         pname = '__tmp_to_csv_from_csv__'
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
@@ -4411,6 +4411,16 @@ def test_slice_with_zero_step_raises(self):
         self.assertRaisesRegexp(ValueError, 'slice step cannot be zero',
                                 lambda: s.ix[::0])
 
+    def test_indexing_assignment_dict_already_exists(self):
+        df = pd.DataFrame({'x': [1, 2, 6],
+                           'y': [2, 2, 8],
+                           'z': [-5, 0, 5]}).set_index('z')
+        expected = df.copy()
+        rhs = dict(x=9, y=99)
+        df.loc[5] = rhs
+        expected.loc[5] = [9, 99]
+        tm.assert_frame_equal(df, expected)
+
 
 class TestSeriesNoneCoercion(tm.TestCase):
     EXPECTED_RESULTS = [