Skip to content

Commit f716c21

Browse files
committed
Merge pull request #5740 from immerrr/fix-empty-frame-dtypes
BUG: return Series as DataFrame.dtypes/ftypes for empty dataframes
2 parents 35a03eb + dfa8ec0 commit f716c21

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ API Changes
6565
- ``select_as_multiple`` will always raise a ``KeyError``, when a key or the selector is not found (:issue:`6177`)
6666
- ``df['col'] = value`` and ``df.loc[:,'col'] = value`` are now completely equivalent;
6767
previously the ``.loc`` would not necessarily coerce the dtype of the resultant series (:issue:`6149`)
68+
- ``dtypes`` and ``ftypes`` now return a series with ``dtype=object`` on empty containers (:issue:`5740`)
6869

6970

7071
Experimental Features

pandas/core/generic.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1947,7 +1947,8 @@ def get_ftype_counts(self):
19471947
def dtypes(self):
19481948
""" Return the dtypes in this object """
19491949
from pandas import Series
1950-
return Series(self._data.get_dtypes(),index=self._info_axis)
1950+
return Series(self._data.get_dtypes(), index=self._info_axis,
1951+
dtype=np.object_)
19511952

19521953
@property
19531954
def ftypes(self):
@@ -1956,7 +1957,8 @@ def ftypes(self):
19561957
in this object.
19571958
"""
19581959
from pandas import Series
1959-
return Series(self._data.get_ftypes(),index=self._info_axis)
1960+
return Series(self._data.get_ftypes(), index=self._info_axis,
1961+
dtype=np.object_)
19601962

19611963
def as_blocks(self, columns=None):
19621964
"""

pandas/tests/test_frame.py

+41
Original file line numberDiff line numberDiff line change
@@ -12164,6 +12164,47 @@ def test_concat_empty_dataframe_dtypes(self):
1216412164
self.assertEqual(result['b'].dtype, np.float64)
1216512165
self.assertEqual(result['c'].dtype, np.float64)
1216612166

12167+
def test_empty_frame_dtypes_ftypes(self):
12168+
empty_df = pd.DataFrame()
12169+
assert_series_equal(empty_df.dtypes, pd.Series(dtype=np.object))
12170+
assert_series_equal(empty_df.ftypes, pd.Series(dtype=np.object))
12171+
12172+
nocols_df = pd.DataFrame(index=[1,2,3])
12173+
assert_series_equal(nocols_df.dtypes, pd.Series(dtype=np.object))
12174+
assert_series_equal(nocols_df.ftypes, pd.Series(dtype=np.object))
12175+
12176+
norows_df = pd.DataFrame(columns=list("abc"))
12177+
assert_series_equal(norows_df.dtypes, pd.Series(np.object, index=list("abc")))
12178+
assert_series_equal(norows_df.ftypes, pd.Series('object:dense', index=list("abc")))
12179+
12180+
norows_int_df = pd.DataFrame(columns=list("abc")).astype(np.int32)
12181+
assert_series_equal(norows_int_df.dtypes, pd.Series(np.dtype('int32'), index=list("abc")))
12182+
assert_series_equal(norows_int_df.ftypes, pd.Series('int32:dense', index=list("abc")))
12183+
12184+
odict = OrderedDict
12185+
df = pd.DataFrame(odict([('a', 1), ('b', True), ('c', 1.0)]), index=[1, 2, 3])
12186+
assert_series_equal(df.dtypes, pd.Series(odict([('a', np.int64),
12187+
('b', np.bool),
12188+
('c', np.float64)])))
12189+
assert_series_equal(df.ftypes, pd.Series(odict([('a', 'int64:dense'),
12190+
('b', 'bool:dense'),
12191+
('c', 'float64:dense')])))
12192+
12193+
# same but for empty slice of df
12194+
assert_series_equal(df[:0].dtypes, pd.Series(odict([('a', np.int),
12195+
('b', np.bool),
12196+
('c', np.float)])))
12197+
assert_series_equal(df[:0].ftypes, pd.Series(odict([('a', 'int64:dense'),
12198+
('b', 'bool:dense'),
12199+
('c', 'float64:dense')])))
12200+
12201+
def skip_if_no_ne(engine='numexpr'):
12202+
if engine == 'numexpr':
12203+
try:
12204+
import numexpr as ne
12205+
except ImportError:
12206+
raise nose.SkipTest("cannot query engine numexpr when numexpr not "
12207+
"installed")
1216712208

1216812209

1216912210
def skip_if_no_pandas_parser(parser):

0 commit comments

Comments
 (0)