mirror of
https://github.com/apache/arrow.git
synced 2026-10-29 09:05:47 +08:00
Add compatibility tests for pre-0.13 metadata. Add Arrow version to pandas metadata
This commit is contained in:
1 parent
0ca1bfc583
commit
670dc6f701
2 files changed
+177
No files matched your search
@@ -245,6 +245,10 @@ def construct_metadata(df, column_names, index_levels, index_descriptors,
|
||||
'index_columns': index_descriptors,
|
||||
'column_indexes': column_indexes,
|
||||
'columns': column_metadata + index_column_metadata,
|
||||
'creator': {
|
||||
'library': 'pyarrow',
|
||||
'version': pa.__version__
|
||||
},
|
||||
'pandas_version': pd.__version__
|
||||
}).encode('utf8')
|
||||
}
|
||||
|
||||
@@ -2539,3 +2539,176 @@ def test_table_from_pandas_columns_and_schema_are_mutually_exclusive():
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
pa.Table.from_pandas(df, schema=schema, columns=columns)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Legacy metadata compatibility tests
|
||||
|
||||
|
||||
def test_range_index_pre_0_12():
|
||||
# Forward compatibility for metadata created from pandas.RangeIndex
|
||||
# prior to pyarrow 0.13.0
|
||||
a_values = [u'foo', u'bar', None, u'baz']
|
||||
b_values = [u'a', u'a', u'b', u'b']
|
||||
a_arrow = pa.array(a_values, type='utf8')
|
||||
b_arrow = pa.array(b_values, type='utf8')
|
||||
|
||||
rng_index_arrow = pa.array([0, 2, 4, 6], type='int64')
|
||||
|
||||
gen_name_0 = '__index_level_0__'
|
||||
gen_name_1 = '__index_level_1__'
|
||||
|
||||
# Case 1: named RangeIndex
|
||||
e1 = pd.DataFrame({
|
||||
'a': a_values
|
||||
}, index=pd.RangeIndex(0, 8, step=2, name='qux'))
|
||||
t1 = pa.Table.from_arrays([a_arrow, rng_index_arrow],
|
||||
names=['a', 'qux'])
|
||||
t1 = t1.replace_schema_metadata({
|
||||
b'pandas': json.dumps(
|
||||
{'index_columns': ['qux'],
|
||||
'column_indexes': [{'name': None,
|
||||
'field_name': None,
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': {'encoding': 'UTF-8'}}],
|
||||
'columns': [{'name': 'a',
|
||||
'field_name': 'a',
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': None},
|
||||
{'name': 'qux',
|
||||
'field_name': 'qux',
|
||||
'pandas_type': 'int64',
|
||||
'numpy_type': 'int64',
|
||||
'metadata': None}],
|
||||
'pandas_version': '0.23.4'}
|
||||
)})
|
||||
r1 = t1.to_pandas()
|
||||
tm.assert_frame_equal(r1, e1)
|
||||
|
||||
# Case 2: named RangeIndex, but conflicts with an actual column
|
||||
e2 = pd.DataFrame({
|
||||
'qux': a_values
|
||||
}, index=pd.RangeIndex(0, 8, step=2, name='qux'))
|
||||
t2 = pa.Table.from_arrays([a_arrow, rng_index_arrow],
|
||||
names=['qux', gen_name_0])
|
||||
t2 = t2.replace_schema_metadata({
|
||||
b'pandas': json.dumps(
|
||||
{'index_columns': [gen_name_0],
|
||||
'column_indexes': [{'name': None,
|
||||
'field_name': None,
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': {'encoding': 'UTF-8'}}],
|
||||
'columns': [{'name': 'a',
|
||||
'field_name': 'a',
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': None},
|
||||
{'name': 'qux',
|
||||
'field_name': gen_name_0,
|
||||
'pandas_type': 'int64',
|
||||
'numpy_type': 'int64',
|
||||
'metadata': None}],
|
||||
'pandas_version': '0.23.4'}
|
||||
)})
|
||||
r2 = t2.to_pandas()
|
||||
tm.assert_frame_equal(r2, e2)
|
||||
|
||||
# Case 3: unnamed RangeIndex
|
||||
e3 = pd.DataFrame({
|
||||
'a': a_values
|
||||
}, index=pd.RangeIndex(0, 8, step=2, name=None))
|
||||
t3 = pa.Table.from_arrays([a_arrow, rng_index_arrow],
|
||||
names=['a', gen_name_0])
|
||||
t3 = t3.replace_schema_metadata({
|
||||
b'pandas': json.dumps(
|
||||
{'index_columns': [gen_name_0],
|
||||
'column_indexes': [{'name': None,
|
||||
'field_name': None,
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': {'encoding': 'UTF-8'}}],
|
||||
'columns': [{'name': 'a',
|
||||
'field_name': 'a',
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': None},
|
||||
{'name': None,
|
||||
'field_name': gen_name_0,
|
||||
'pandas_type': 'int64',
|
||||
'numpy_type': 'int64',
|
||||
'metadata': None}],
|
||||
'pandas_version': '0.23.4'}
|
||||
)})
|
||||
r3 = t3.to_pandas()
|
||||
tm.assert_frame_equal(r3, e3)
|
||||
|
||||
# Case 4: MultiIndex with named RangeIndex
|
||||
e4 = pd.DataFrame({
|
||||
'a': a_values
|
||||
}, index=[pd.RangeIndex(0, 8, step=2, name='qux'), b_values])
|
||||
t4 = pa.Table.from_arrays([a_arrow, rng_index_arrow, b_arrow],
|
||||
names=['a', 'qux', gen_name_1])
|
||||
t4 = t4.replace_schema_metadata({
|
||||
b'pandas': json.dumps(
|
||||
{'index_columns': ['qux', gen_name_1],
|
||||
'column_indexes': [{'name': None,
|
||||
'field_name': None,
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': {'encoding': 'UTF-8'}}],
|
||||
'columns': [{'name': 'a',
|
||||
'field_name': 'a',
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': None},
|
||||
{'name': 'qux',
|
||||
'field_name': 'qux',
|
||||
'pandas_type': 'int64',
|
||||
'numpy_type': 'int64',
|
||||
'metadata': None},
|
||||
{'name': None,
|
||||
'field_name': gen_name_1,
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': None}],
|
||||
'pandas_version': '0.23.4'}
|
||||
)})
|
||||
r4 = t4.to_pandas()
|
||||
tm.assert_frame_equal(r4, e4)
|
||||
|
||||
# Case 4: MultiIndex with unnamed RangeIndex
|
||||
e5 = pd.DataFrame({
|
||||
'a': a_values
|
||||
}, index=[pd.RangeIndex(0, 8, step=2, name=None), b_values])
|
||||
t5 = pa.Table.from_arrays([a_arrow, rng_index_arrow, b_arrow],
|
||||
names=['a', gen_name_0, gen_name_1])
|
||||
t5 = t5.replace_schema_metadata({
|
||||
b'pandas': json.dumps(
|
||||
{'index_columns': [gen_name_0, gen_name_1],
|
||||
'column_indexes': [{'name': None,
|
||||
'field_name': None,
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': {'encoding': 'UTF-8'}}],
|
||||
'columns': [{'name': 'a',
|
||||
'field_name': 'a',
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': None},
|
||||
{'name': None,
|
||||
'field_name': gen_name_0,
|
||||
'pandas_type': 'int64',
|
||||
'numpy_type': 'int64',
|
||||
'metadata': None},
|
||||
{'name': None,
|
||||
'field_name': gen_name_1,
|
||||
'pandas_type': 'unicode',
|
||||
'numpy_type': 'object',
|
||||
'metadata': None}],
|
||||
'pandas_version': '0.23.4'}
|
||||
)})
|
||||
r5 = t5.to_pandas()
|
||||
tm.assert_frame_equal(r5, e5)
|
||||
Reference in new issue
Block a user