# -*- coding: utf-8 -*- import collections from collections import OrderedDict, defaultdict from datetime import datetime import numpy as np import pytest import pytz from pandas.compat import long from pandas import DataFrame, MultiIndex, Series, Timestamp, compat, date_range from pandas.tests.frame.common import TestData import pandas.util.testing as tm class TestDataFrameConvertTo(TestData): def test_to_dict_timestamp(self): # GH11247 # split/records producing np.datetime64 rather than Timestamps # on datetime64[ns] dtypes only tsmp = Timestamp('20130101') test_data = DataFrame({'A': [tsmp, tsmp], 'B': [tsmp, tsmp]}) test_data_mixed = DataFrame({'A': [tsmp, tsmp], 'B': [1, 2]}) expected_records = [{'A': tsmp, 'B': tsmp}, {'A': tsmp, 'B': tsmp}] expected_records_mixed = [{'A': tsmp, 'B': 1}, {'A': tsmp, 'B': 2}] assert (test_data.to_dict(orient='records') == expected_records) assert (test_data_mixed.to_dict(orient='records') == expected_records_mixed) expected_series = { 'A': Series([tsmp, tsmp], name='A'), 'B': Series([tsmp, tsmp], name='B'), } expected_series_mixed = { 'A': Series([tsmp, tsmp], name='A'), 'B': Series([1, 2], name='B'), } tm.assert_dict_equal(test_data.to_dict(orient='series'), expected_series) tm.assert_dict_equal(test_data_mixed.to_dict(orient='series'), expected_series_mixed) expected_split = { 'index': [0, 1], 'data': [[tsmp, tsmp], [tsmp, tsmp]], 'columns': ['A', 'B'] } expected_split_mixed = { 'index': [0, 1], 'data': [[tsmp, 1], [tsmp, 2]], 'columns': ['A', 'B'] } tm.assert_dict_equal(test_data.to_dict(orient='split'), expected_split) tm.assert_dict_equal(test_data_mixed.to_dict(orient='split'), expected_split_mixed) def test_to_dict_index_not_unique_with_index_orient(self): # GH22801 # Data loss when indexes are not unique. Raise ValueError. df = DataFrame({'a': [1, 2], 'b': [0.5, 0.75]}, index=['A', 'A']) pytest.raises(ValueError, df.to_dict, orient='index') def test_to_dict_invalid_orient(self): df = DataFrame({'A': [0, 1]}) pytest.raises(ValueError, df.to_dict, orient='xinvalid') def test_to_records_dt64(self): df = DataFrame([["one", "two", "three"], ["four", "five", "six"]], index=date_range("2012-01-01", "2012-01-02")) # convert_datetime64 defaults to None expected = df.index.values[0] result = df.to_records()['index'][0] assert expected == result # check for FutureWarning if convert_datetime64=False is passed with tm.assert_produces_warning(FutureWarning): expected = df.index.values[0] result = df.to_records(convert_datetime64=False)['index'][0] assert expected == result # check for FutureWarning if convert_datetime64=True is passed with tm.assert_produces_warning(FutureWarning): expected = df.index[0] result = df.to_records(convert_datetime64=True)['index'][0] assert expected == result def test_to_records_with_multindex(self): # GH3189 index = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] data = np.zeros((8, 4)) df = DataFrame(data, index=index) r = df.to_records(index=True)['level_0'] assert 'bar' in r assert 'one' not in r def test_to_records_with_Mapping_type(self): import email from email.parser import Parser compat.Mapping.register(email.message.Message) headers = Parser().parsestr('From: \n' 'To: \n' 'Subject: Test message\n' '\n' 'Body would go here\n') frame = DataFrame.from_records([headers]) all(x in frame for x in ['Type', 'Subject', 'From']) def test_to_records_floats(self): df = DataFrame(np.random.rand(10, 10)) df.to_records() def test_to_records_index_name(self): df = DataFrame(np.random.randn(3, 3)) df.index.name = 'X' rs = df.to_records() assert 'X' in rs.dtype.fields df = DataFrame(np.random.randn(3, 3)) rs = df.to_records() assert 'index' in rs.dtype.fields df.index = MultiIndex.from_tuples([('a', 'x'), ('a', 'y'), ('b', 'z')]) df.index.names = ['A', None] rs = df.to_records() assert 'level_0' in rs.dtype.fields def test_to_records_with_unicode_index(self): # GH13172 # unicode_literals conflict with to_records result = DataFrame([{u'a': u'x', u'b': 'y'}]).set_index(u'a') \ .to_records() expected = np.rec.array([('x', 'y')], dtype=[('a', 'O'), ('b', 'O')]) tm.assert_almost_equal(result, expected) def test_to_records_with_unicode_column_names(self): # xref issue: https://github.com/numpy/numpy/issues/2407 # Issue #11879. to_records used to raise an exception when used # with column names containing non-ascii characters in Python 2 result = DataFrame(data={u"accented_name_é": [1.0]}).to_records() # Note that numpy allows for unicode field names but dtypes need # to be specified using dictionary instead of list of tuples. expected = np.rec.array( [(0, 1.0)], dtype={"names": ["index", u"accented_name_é"], "formats": ['=i8', '=f8']} ) tm.assert_almost_equal(result, expected) def test_to_records_with_categorical(self): # GH8626 # dict creation df = DataFrame({'A': list('abc')}, dtype='category') expected = Series(list('abc'), dtype='category', name='A') tm.assert_series_equal(df['A'], expected) # list-like creation df = DataFrame(list('abc'), dtype='category') expected = Series(list('abc'), dtype='category', name=0) tm.assert_series_equal(df[0], expected) # to record array # this coerces result = df.to_records() expected = np.rec.array([(0, 'a'), (1, 'b'), (2, 'c')], dtype=[('index', '=i8'), ('0', 'O')]) tm.assert_almost_equal(result, expected) @pytest.mark.parametrize("kwargs,expected", [ # No dtypes --> default to array dtypes. (dict(), np.rec.array([(0, 1, 0.2, "a"), (1, 2, 1.5, "bc")], dtype=[("index", "