|
12 | 12 | from pandas.io.json.table_schema import (
|
13 | 13 | as_json_table_type,
|
14 | 14 | build_table_schema,
|
15 |
| - make_field, |
| 15 | + convert_pandas_type_to_json_field, |
| 16 | + convert_json_field_to_pandas_type, |
16 | 17 | set_default_names)
|
17 | 18 | import pandas.util.testing as tm
|
18 | 19 |
|
@@ -335,62 +336,89 @@ def test_date_format_raises(self):
|
335 | 336 | self.df.to_json(orient='table', date_format='iso')
|
336 | 337 | self.df.to_json(orient='table')
|
337 | 338 |
|
338 |
| - def test_make_field_int(self): |
| 339 | + def test_convert_pandas_type_to_json_field_int(self): |
339 | 340 | data = [1, 2, 3]
|
340 | 341 | kinds = [pd.Series(data, name='name'), pd.Index(data, name='name')]
|
341 | 342 | for kind in kinds:
|
342 |
| - result = make_field(kind) |
| 343 | + result = convert_pandas_type_to_json_field(kind) |
343 | 344 | expected = {"name": "name", "type": 'integer'}
|
344 | 345 | assert result == expected
|
345 | 346 |
|
346 |
| - def test_make_field_float(self): |
| 347 | + def test_convert_pandas_type_to_json_field_float(self): |
347 | 348 | data = [1., 2., 3.]
|
348 | 349 | kinds = [pd.Series(data, name='name'), pd.Index(data, name='name')]
|
349 | 350 | for kind in kinds:
|
350 |
| - result = make_field(kind) |
| 351 | + result = convert_pandas_type_to_json_field(kind) |
351 | 352 | expected = {"name": "name", "type": 'number'}
|
352 | 353 | assert result == expected
|
353 | 354 |
|
354 |
| - def test_make_field_datetime(self): |
| 355 | + def test_convert_pandas_type_to_json_field_datetime(self): |
355 | 356 | data = [1., 2., 3.]
|
356 | 357 | kinds = [pd.Series(pd.to_datetime(data), name='values'),
|
357 | 358 | pd.to_datetime(data)]
|
358 | 359 | for kind in kinds:
|
359 |
| - result = make_field(kind) |
| 360 | + result = convert_pandas_type_to_json_field(kind) |
360 | 361 | expected = {"name": "values", "type": 'datetime'}
|
361 | 362 | assert result == expected
|
362 | 363 |
|
363 | 364 | kinds = [pd.Series(pd.to_datetime(data, utc=True), name='values'),
|
364 | 365 | pd.to_datetime(data, utc=True)]
|
365 | 366 | for kind in kinds:
|
366 |
| - result = make_field(kind) |
| 367 | + result = convert_pandas_type_to_json_field(kind) |
367 | 368 | expected = {"name": "values", "type": 'datetime', "tz": "UTC"}
|
368 | 369 | assert result == expected
|
369 | 370 |
|
370 | 371 | arr = pd.period_range('2016', freq='A-DEC', periods=4)
|
371 |
| - result = make_field(arr) |
| 372 | + result = convert_pandas_type_to_json_field(arr) |
372 | 373 | expected = {"name": "values", "type": 'datetime', "freq": "A-DEC"}
|
373 | 374 | assert result == expected
|
374 | 375 |
|
375 |
| - def test_make_field_categorical(self): |
| 376 | + def test_convert_pandas_type_to_json_field_categorical(self): |
376 | 377 | data = ['a', 'b', 'c']
|
377 | 378 | ordereds = [True, False]
|
378 | 379 |
|
379 | 380 | for ordered in ordereds:
|
380 | 381 | arr = pd.Series(pd.Categorical(data, ordered=ordered), name='cats')
|
381 |
| - result = make_field(arr) |
| 382 | + result = convert_pandas_type_to_json_field(arr) |
382 | 383 | expected = {"name": "cats", "type": "any",
|
383 | 384 | "constraints": {"enum": data},
|
384 | 385 | "ordered": ordered}
|
385 | 386 | assert result == expected
|
386 | 387 |
|
387 | 388 | arr = pd.CategoricalIndex(data, ordered=ordered, name='cats')
|
388 |
| - result = make_field(arr) |
| 389 | + result = convert_pandas_type_to_json_field(arr) |
389 | 390 | expected = {"name": "cats", "type": "any",
|
390 | 391 | "constraints": {"enum": data},
|
391 | 392 | "ordered": ordered}
|
392 | 393 | assert result == expected
|
393 | 394 |
|
| 395 | + @pytest.mark.parametrize("inp,exp", [ |
| 396 | + ({'type': 'integer'}, 'int64'), |
| 397 | + ({'type': 'number'}, 'float64'), |
| 398 | + ({'type': 'boolean'}, 'bool'), |
| 399 | + ({'type': 'duration'}, 'timedelta64'), |
| 400 | + ({'type': 'datetime'}, 'datetime64[ns]'), |
| 401 | + ({'type': 'datetime', 'tz': 'US/Hawaii'}, 'datetime64[ns, US/Hawaii]'), |
| 402 | + ({'type': 'any'}, 'object'), |
| 403 | + ({'type': 'any', 'constraints': {'enum': ['a', 'b', 'c']}, |
| 404 | + 'ordered': False}, CategoricalDtype(categories=['a', 'b', 'c'], |
| 405 | + ordered=False)), |
| 406 | + ({'type': 'any', 'constraints': {'enum': ['a', 'b', 'c']}, |
| 407 | + 'ordered': True}, CategoricalDtype(categories=['a', 'b', 'c'], |
| 408 | + ordered=True)), |
| 409 | + ({'type': 'string'}, 'object')]) |
| 410 | + def test_convert_json_field_to_pandas_type(self, inp, exp): |
| 411 | + field = {'name': 'foo'} |
| 412 | + field.update(inp) |
| 413 | + assert convert_json_field_to_pandas_type(field) == exp |
| 414 | + |
| 415 | + @pytest.mark.parametrize("inp", ["geopoint", "geojson", "fake_type"]) |
| 416 | + def test_convert_json_field_to_pandas_type_raises(self, inp): |
| 417 | + field = {'type': inp} |
| 418 | + with tm.assert_raises_regex(ValueError, "Unsupported or invalid field " |
| 419 | + "type: {}".format(inp)): |
| 420 | + convert_json_field_to_pandas_type(field) |
| 421 | + |
394 | 422 | def test_categorical(self):
|
395 | 423 | s = pd.Series(pd.Categorical(['a', 'b', 'a']))
|
396 | 424 | s.index.name = 'idx'
|
@@ -476,92 +504,32 @@ def test_mi_falsey_name(self):
|
476 | 504 |
|
477 | 505 | class TestTableOrientReader(object):
|
478 | 506 |
|
479 |
| - def test_integer(self): |
480 |
| - df = DataFrame( |
481 |
| - {'A': [1, 2, 3, 4], |
482 |
| - }, |
483 |
| - index=pd.Index(range(4), name='idx')) |
484 |
| - out = df.to_json(orient="table") |
485 |
| - result = pd.read_json(out, orient="table") |
486 |
| - tm.assert_frame_equal(df, result) |
487 |
| - |
488 |
| - def test_object(self): |
489 |
| - df = DataFrame( |
490 |
| - {'B': ['a', 'b', 'c', 'c'], |
491 |
| - }, |
492 |
| - index=pd.Index(range(4), name='idx')) |
493 |
| - out = df.to_json(orient="table") |
494 |
| - result = pd.read_json(out, orient="table") |
495 |
| - tm.assert_frame_equal(df, result) |
496 |
| - |
497 |
| - def test_date_range(self): |
498 |
| - df = DataFrame( |
499 |
| - {'C': pd.date_range('2016-01-01', freq='d', periods=4), |
500 |
| - }, |
501 |
| - index=pd.Index(range(4), name='idx')) |
502 |
| - |
503 |
| - out = df.to_json(orient="table") |
504 |
| - result = pd.read_json(out, orient="table") |
505 |
| - tm.assert_frame_equal(df, result) |
506 |
| - |
507 |
| - def test_timedelta_raises(self): |
508 |
| - df = DataFrame( |
509 |
| - {'D': pd.timedelta_range('1H', periods=4, freq='T'), |
510 |
| - }, |
511 |
| - index=pd.Index(range(4), name='idx')) |
512 |
| - |
513 |
| - out = df.to_json(orient="table") |
514 |
| - with tm.assert_raises_regex(NotImplementedError, 'can not yet read ' |
515 |
| - 'ISO-formatted Timedelta data'): |
516 |
| - pd.read_json(out, orient="table") |
517 |
| - |
518 |
| - def test_categorical(self): |
519 |
| - df = DataFrame( |
520 |
| - {'E': pd.Series(pd.Categorical(['a', 'b', 'c', 'c'])), |
521 |
| - 'F': pd.Series(pd.Categorical(['a', 'b', 'c', 'c'], |
522 |
| - ordered=True)), |
523 |
| - }, |
524 |
| - index=pd.Index(range(4), name='idx')) |
525 |
| - |
| 507 | + @pytest.mark.parametrize("vals", [ |
| 508 | + {'ints': [1, 2, 3, 4]}, |
| 509 | + {'objects': ['a', 'b', 'c', 'd']}, |
| 510 | + {'date_ranges': pd.date_range('2016-01-01', freq='d', periods=4)}, |
| 511 | + {'categoricals': pd.Series(pd.Categorical(['a', 'b', 'c', 'c']))}, |
| 512 | + {'ordered_cats': pd.Series(pd.Categorical(['a', 'b', 'c', 'c'], |
| 513 | + ordered=True))}, |
| 514 | + pytest.param({'floats': [1., 2., 3., 4.]}, marks=pytest.mark.xfail), |
| 515 | + {'floats': [1.1, 2.2, 3.3, 4.4]}, |
| 516 | + {'bools': [True, False, False, True]}]) |
| 517 | + def test_read_json_table_orient(self, vals): |
| 518 | + df = DataFrame(vals, index=pd.Index(range(4), name='idx')) |
526 | 519 | out = df.to_json(orient="table")
|
527 | 520 | result = pd.read_json(out, orient="table")
|
528 | 521 | tm.assert_frame_equal(df, result)
|
529 | 522 |
|
530 |
| - @pytest.mark.parametrize("float_vals", [ |
531 |
| - pytest.param([1., 2., 3., 4.], marks=pytest.mark.xfail), |
532 |
| - [1.1, 2.2, 3.3, 4.4]]) |
533 |
| - def test_float(self, float_vals): |
534 |
| - df = DataFrame( |
535 |
| - {'G': float_vals, |
536 |
| - }, |
537 |
| - index=pd.Index(range(4), name='idx')) |
538 |
| - |
| 523 | + @pytest.mark.parametrize("vals", [ |
| 524 | + {'timedeltas': pd.timedelta_range('1H', periods=4, freq='T')}, |
| 525 | + {'timezones': pd.date_range('2016-01-01', freq='d', periods=4, |
| 526 | + tz='US/Central')}]) |
| 527 | + def test_read_json_table_orient_raises(self, vals): |
| 528 | + df = DataFrame(vals, index=pd.Index(range(4), name='idx')) |
539 | 529 | out = df.to_json(orient="table")
|
540 |
| - result = pd.read_json(out, orient="table", convert_axes=False) |
541 |
| - tm.assert_frame_equal(df, result) |
542 |
| - |
543 |
| - def test_timezone_raises(self): |
544 |
| - df = DataFrame( |
545 |
| - {'H': pd.date_range('2016-01-01', freq='d', periods=4, |
546 |
| - tz='US/Central'), |
547 |
| - }, |
548 |
| - index=pd.Index(range(4), name='idx')) |
549 |
| - |
550 |
| - out = df.to_json(orient="table") |
551 |
| - with tm.assert_raises_regex(NotImplementedError, 'can not yet read ' |
552 |
| - 'timezone data'): |
| 530 | + with tm.assert_raises_regex(NotImplementedError, 'can not yet read '): |
553 | 531 | pd.read_json(out, orient="table")
|
554 | 532 |
|
555 |
| - def test_bool(self): |
556 |
| - df = DataFrame( |
557 |
| - {'I': [True, False, False, True], |
558 |
| - }, |
559 |
| - index=pd.Index(range(4), name='idx')) |
560 |
| - |
561 |
| - out = df.to_json(orient="table") |
562 |
| - result = pd.read_json(out, orient="table") |
563 |
| - tm.assert_frame_equal(df, result) |
564 |
| - |
565 | 533 | def test_comprehensive(self):
|
566 | 534 | df = DataFrame(
|
567 | 535 | {'A': [1, 2, 3, 4],
|
|
0 commit comments