Repository: pandas-dev/pandas

Issue:
DataFrame creation incorrect error message
The problem was already mentioned as part of other issues, but still persists in 0.22

https://github.com/pandas-dev/pandas/issues/8020
https://github.com/blaze/blaze/issues/466

Reported both expected shape and input data shape are both transposed which causes a lot of confusion. In my opinion, the reference value should be ` DataFrame.shape`.
```python
my_arr = np.array([1, 2, 3])
print("my_arr.shape: {}".format(my_arr.shape))
df = pd.DataFrame(index=[0], columns=range(0, 4), data=my_arr)
```

```python
my_arr.shape: (3,)
Traceback (most recent call last):
...
ValueError: Shape of passed values is (1, 3), indices imply (4, 1)
```

Below are shapes which are expected to be reported:
```python
my_arr = np.array([[0, 1, 2, 3]])
print("my_arr.shape: {}".format(my_arr.shape))
df = pd.DataFrame(index=[0], columns=range(0, 4), data=my_arr)
print(df.shape)`
```
```python
my_arr.shape: (1, 4)
(1, 4)
```

I'm not sure, whether this is another issue, but in the first example, the error cause is 1-dimensional data while constructor expects 2-dimensional data. The user gets no hint about this from the error message.


Discussion:
the first example is wrong. The block manager reports this, but doesn't flip the dim (like we do for everything else), so would welcome a PR to correct that.

I don't see a problem with the 2nd. You gave a 1, 4 array. That's the same as the dim of the frame, so it constructs.

Resolving patch:
diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py
--- a/pandas/core/internals/managers.py
+++ b/pandas/core/internals/managers.py
@@ -1674,7 +1674,15 @@ def create_block_manager_from_arrays(arrays, names, axes):
 def construction_error(tot_items, block_shape, axes, e=None):
     """ raise a helpful message about our construction """
     passed = tuple(map(int, [tot_items] + list(block_shape)))
-    implied = tuple(map(int, [len(ax) for ax in axes]))
+    # Correcting the user facing error message during dataframe construction
+    if len(passed) <= 2:
+        passed = passed[::-1]
+
+    implied = tuple(len(ax) for ax in axes)
+    # Correcting the user facing error message during dataframe construction
+    if len(implied) <= 2:
+        implied = implied[::-1]
+
     if passed == implied and e is not None:
         raise e
     if block_shape[0] == 0:


Test patch:
diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py
--- a/pandas/tests/frame/test_constructors.py
+++ b/pandas/tests/frame/test_constructors.py
@@ -386,25 +386,35 @@ def test_constructor_error_msgs(self):
                        'B': ['a', 'b', 'c']})
 
         # wrong size ndarray, GH 3105
-        msg = r"Shape of passed values is \(3, 4\), indices imply \(3, 3\)"
+        msg = r"Shape of passed values is \(4, 3\), indices imply \(3, 3\)"
         with pytest.raises(ValueError, match=msg):
             DataFrame(np.arange(12).reshape((4, 3)),
                       columns=['foo', 'bar', 'baz'],
                       index=pd.date_range('2000-01-01', periods=3))
 
+        arr = np.array([[4, 5, 6]])
+        msg = r"Shape of passed values is \(1, 3\), indices imply \(1, 4\)"
+        with pytest.raises(ValueError, match=msg):
+            DataFrame(index=[0], columns=range(0, 4), data=arr)
+
+        arr = np.array([4, 5, 6])
+        msg = r"Shape of passed values is \(3, 1\), indices imply \(1, 4\)"
+        with pytest.raises(ValueError, match=msg):
+            DataFrame(index=[0], columns=range(0, 4), data=arr)
+
         # higher dim raise exception
         with pytest.raises(ValueError, match='Must pass 2-d input'):
             DataFrame(np.zeros((3, 3, 3)), columns=['A', 'B', 'C'], index=[1])
 
         # wrong size axis labels
         msg = ("Shape of passed values "
-               r"is \(3, 2\), indices "
-               r"imply \(3, 1\)")
+               r"is \(2, 3\), indices "
+               r"imply \(1, 3\)")
         with pytest.raises(ValueError, match=msg):
             DataFrame(np.random.rand(2, 3), columns=['A', 'B', 'C'], index=[1])
 
         msg = ("Shape of passed values "
-               r"is \(3, 2\), indices "
+               r"is \(2, 3\), indices "
                r"imply \(2, 2\)")
         with pytest.raises(ValueError, match=msg):
             DataFrame(np.random.rand(2, 3), columns=['A', 'B'], index=[1, 2])
@@ -638,10 +648,10 @@ def _check_basic_constructor(self, empty):
         assert frame.values.dtype == np.int64
 
         # wrong size axis labels
-        msg = r'Shape of passed values is \(3, 2\), indices imply \(3, 1\)'
+        msg = r'Shape of passed values is \(2, 3\), indices imply \(1, 3\)'
         with pytest.raises(ValueError, match=msg):
             DataFrame(mat, columns=['A', 'B', 'C'], index=[1])
-        msg = r'Shape of passed values is \(3, 2\), indices imply \(2, 2\)'
+        msg = r'Shape of passed values is \(2, 3\), indices imply \(2, 2\)'
         with pytest.raises(ValueError, match=msg):
             DataFrame(mat, columns=['A', 'B'], index=[1, 2])
 
@@ -1805,7 +1815,7 @@ def test_from_records_to_records(self):
         tm.assert_frame_equal(DataFrame.from_records(arr2), DataFrame(arr2))
 
         # wrong length
-        msg = r'Shape of passed values is \(3, 2\), indices imply \(3, 1\)'
+        msg = r'Shape of passed values is \(2, 3\), indices imply \(1, 3\)'
         with pytest.raises(ValueError, match=msg):
             DataFrame.from_records(arr, index=index[:-1])
 
diff --git a/pandas/tests/io/json/test_pandas.py b/pandas/tests/io/json/test_pandas.py
--- a/pandas/tests/io/json/test_pandas.py
+++ b/pandas/tests/io/json/test_pandas.py
@@ -346,7 +346,7 @@ def test_frame_from_json_bad_data(self):
         json = StringIO('{"columns":["A","B"],'
                         '"index":["2","3"],'
                         '"data":[[1.0,"1"],[2.0,"2"],[null,"3"]]}')
-        msg = r"Shape of passed values is \(2, 3\), indices imply \(2, 2\)"
+        msg = r"Shape of passed values is \(3, 2\), indices imply \(2, 2\)"
         with pytest.raises(ValueError, match=msg):
             read_json(json, orient="split")