Skip to content

Commit cb7c6ae

Browse files
committed
ENH: Add JSON export option for DataFrame #631
Bundle custom ujson lib for DataFrame and Series JSON export & import.
1 parent d3c3f51 commit cb7c6ae

13 files changed

+5702
-2
lines changed

pandas/core/frame.py

+87
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,93 @@ def to_dict(self):
679679
"""
680680
return dict((k, v.to_dict()) for k, v in self.iteritems())
681681

682+
@classmethod
683+
def from_json(cls, json, orient="columns", dtype=None, numpy=True):
684+
"""
685+
Convert JSON string to DataFrame
686+
687+
Parameters
688+
----------
689+
json : The JSON string to parse.
690+
orient : {'split', 'records', 'index', 'columns', 'values'},
691+
default 'columns'
692+
The format of the JSON string
693+
split : dict like
694+
{index -> [index], columns -> [columns], data -> [values]}
695+
records : list like [{column -> value}, ... , {column -> value}]
696+
index : dict like {index -> {column -> value}}
697+
columns : dict like {column -> {index -> value}}
698+
values : just the values array
699+
dtype : dtype of the resulting DataFrame
700+
nupmpy: direct decoding to numpy arrays. default True but falls back
701+
to standard decoding if a problem occurs.
702+
703+
Returns
704+
-------
705+
result : DataFrame
706+
"""
707+
from pandas._ujson import loads
708+
df = None
709+
710+
if numpy:
711+
try:
712+
if orient == "columns":
713+
args = loads(json, dtype=dtype, numpy=True, labelled=True)
714+
if args:
715+
args = (args[0].T, args[2], args[1])
716+
df = DataFrame(*args)
717+
elif orient == "split":
718+
df = DataFrame(**loads(json, dtype=dtype, numpy=True))
719+
elif orient == "values":
720+
df = DataFrame(loads(json, dtype=dtype, numpy=True))
721+
else:
722+
df = DataFrame(*loads(json, dtype=dtype, numpy=True,
723+
labelled=True))
724+
except ValueError:
725+
numpy = False
726+
if not numpy:
727+
if orient == "columns":
728+
df = DataFrame(loads(json), dtype=dtype)
729+
elif orient == "split":
730+
df = DataFrame(dtype=dtype, **loads(json))
731+
elif orient == "index":
732+
df = DataFrame(loads(json), dtype=dtype).T
733+
else:
734+
df = DataFrame(loads(json), dtype=dtype)
735+
736+
return df
737+
738+
def to_json(self, orient="columns", double_precision=10,
739+
force_ascii=True):
740+
"""
741+
Convert DataFrame to a JSON string.
742+
743+
Note NaN's and None will be converted to null and datetime objects
744+
will be converted to UNIX timestamps.
745+
746+
Parameters
747+
----------
748+
orient : {'split', 'records', 'index', 'columns', 'values'},
749+
default 'columns'
750+
The format of the JSON string
751+
split : dict like
752+
{index -> [index], columns -> [columns], data -> [values]}
753+
records : list like [{column -> value}, ... , {column -> value}]
754+
index : dict like {index -> {column -> value}}
755+
columns : dict like {column -> {index -> value}}
756+
values : just the values array
757+
double_precision : The number of decimal places to use when encoding
758+
floating point values, default 10.
759+
force_ascii : force encoded string to be ASCII, default True.
760+
761+
Returns
762+
-------
763+
result : JSON compatible string
764+
"""
765+
from pandas._ujson import dumps
766+
return dumps(self, orient=orient, double_precision=double_precision,
767+
ensure_ascii=force_ascii)
768+
682769
@classmethod
683770
def from_records(cls, data, index=None, exclude=None, columns=None,
684771
names=None, coerce_float=False):

pandas/core/series.py

+71
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,77 @@ def to_dict(self):
911911
"""
912912
return dict(self.iteritems())
913913

914+
@classmethod
915+
def from_json(cls, json, orient="index", dtype=None, numpy=True):
916+
"""
917+
Convert JSON string to Series
918+
919+
Parameters
920+
----------
921+
json : The JSON string to parse.
922+
orient : {'split', 'records', 'index'}, default 'index'
923+
The format of the JSON string
924+
split : dict like
925+
{index -> [index], name -> name, data -> [values]}
926+
records : list like [value, ... , value]
927+
index : dict like {index -> value}
928+
dtype : dtype of the resulting Series
929+
nupmpy: direct decoding to numpy arrays. default True but falls back
930+
to standard decoding if a problem occurs.
931+
932+
Returns
933+
-------
934+
result : Series
935+
"""
936+
from pandas._ujson import loads
937+
s = None
938+
939+
if numpy:
940+
try:
941+
if orient == "split":
942+
s = Series(**loads(json, dtype=dtype, numpy=True))
943+
elif orient == "columns" or orient == "index":
944+
s = Series(*loads(json, dtype=dtype, numpy=True,
945+
labelled=True))
946+
else:
947+
s = Series(loads(json, dtype=dtype, numpy=True))
948+
except ValueError:
949+
numpy = False
950+
if not numpy:
951+
if orient == "split":
952+
s = Series(dtype=dtype, **loads(json))
953+
else:
954+
s = Series(loads(json), dtype=dtype)
955+
956+
return s
957+
958+
def to_json(self, orient="index", double_precision=10, force_ascii=True):
959+
"""
960+
Convert Series to a JSON string
961+
962+
Note NaN's and None will be converted to null and datetime objects
963+
will be converted to UNIX timestamps.
964+
965+
Parameters
966+
----------
967+
orient : {'split', 'records', 'index'}, default 'index'
968+
The format of the JSON string
969+
split : dict like
970+
{index -> [index], name -> name, data -> [values]}
971+
records : list like [value, ... , value]
972+
index : dict like {index -> value}
973+
double_precision : The number of decimal places to use when encoding
974+
floating point values, default 10.
975+
force_ascii : force encoded string to be ASCII, default True.
976+
977+
Returns
978+
-------
979+
result : JSON compatible string
980+
"""
981+
from pandas._ujson import dumps
982+
return dumps(self, orient=orient, double_precision=double_precision,
983+
ensure_ascii=force_ascii)
984+
914985
def to_sparse(self, kind='block', fill_value=None):
915986
"""
916987
Convert Series to SparseSeries

0 commit comments

Comments
 (0)