熊猫读取 json 不适用于 MultiIndex
Posted
技术标签:
【中文标题】熊猫读取 json 不适用于 MultiIndex【英文标题】:pandas read json not working on MultiIndex 【发布时间】:2014-05-11 05:04:46 【问题描述】:我正在尝试通过pd.read_json
读取通过df.to_json()
创建的数据框,但我得到的是ValueError
。我认为这可能与索引是 MultiIndex 的事实有关,但我不确定如何处理。
55k 行的原始数据框称为psi
,我通过以下方式创建了test.json
:
psi.head().to_json('test.json')
Here是print psi.head().to_string()
的输出,如果你想使用的话。
当我对这一小组数据(5 行)执行此操作时,我得到一个 ValueError
。
! wget --no-check-certificate https://gist.githubusercontent.com/olgabot/9897953/raw/c270d8cf1b736676783cc1372b4f8106810a14c5/test.json
import pandas as pd
pd.read_json('test.json')
这是完整的堆栈:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-14-1de2f0e65268> in <module>()
1 get_ipython().system(u' wget https://gist.githubusercontent.com/olgabot/9897953/raw/c270d8cf1b736676783cc1372b4f8106810a14c5/test.json'>)
2 import pandas as pd
----> 3 pd.read_json('test.json')
/home/obot/virtualenvs/envy/lib/python2.7/site-packages/pandas/io/json.pyc in read_json(path_or_buf, orient, typ, dtype, convert_axes, convert_dates, keep_default_dates, numpy, precise_float, date_unit)
196 obj = FrameParser(json, orient, dtype, convert_axes, convert_dates,
197 keep_default_dates, numpy, precise_float,
--> 198 date_unit).parse()
199
200 if typ == 'series' or obj is None:
/home/obot/virtualenvs/envy/lib/python2.7/site-packages/pandas/io/json.pyc in parse(self)
264
265 else:
--> 266 self._parse_no_numpy()
267
268 if self.obj is None:
/home/obot/virtualenvs/envy/lib/python2.7/site-packages/pandas/io/json.pyc in _parse_no_numpy(self)
481 if orient == "columns":
482 self.obj = DataFrame(
--> 483 loads(json, precise_float=self.precise_float), dtype=None)
484 elif orient == "split":
485 decoded = dict((str(k), v)
ValueError: No ':' found when decoding object value
> /home/obot/virtualenvs/envy/lib/python2.7/site-packages/pandas/io/json.py(483)_parse_no_numpy()
482 self.obj = DataFrame(
--> 483 loads(json, precise_float=self.precise_float), dtype=None)
484 elif orient == "split":
但是当我在整个数据帧(55k 行)上执行此操作时,我得到一个invalid pointer error 并且 IPython 内核死了。有什么想法吗?
编辑:首先添加了 json 的生成方式。
【问题讨论】:
这不是有效的 JSON。我想问题在于它最初是如何创建的。你有创建它的示例代码吗? 未实施,请参见此处:github.com/pydata/pandas/issues/4889 @Jeff:如果to_json
生成无效的 JSON 似乎仍然很糟糕。这是发生了什么,还是这里有其他错误?
嗯,这是阅读它。欢迎有 PR 来修复它(虽然它有点不重要)。
@Jeff:是的,但她说她使用to_json
创建了 JSON(但没有具体说明如何)。
【参考方案1】:
这不是 ATM 实现的,请在此处查看问题:https://github.com/pydata/pandas/issues/4889。
您可以简单地先重置索引,例如
df.reset_index().to_json(...)
它会起作用的。
【讨论】:
它不适用于 pandas 1.3.0 我在使用df.reset_index().to_json(orient="table")
时收到错误 NotImplementedError: orient='table' is not supported for MultiIndex columns
【参考方案2】:
或者你可以用 orient = 'table' 写 json
df.to_json(path_or_buf='test.json', orient='table')
读取多索引json
pd.read_json('test.json', orient='table')
【讨论】:
它为我加载了满是 NaN 的表=(但具有与初始 df 相同的 MultiIndex 结构。 在 pandas 1.0.1 中获取NotImplementedError: orient='table' is not supported for MultiIndex
我相信使用 pandas v1+,您需要提供 typ == 'frame'
然后它接受 orient 表。 pandas.pydata.org/docs/reference/api/…【参考方案3】:
如果要返回 MultiIndex 结构:
# save MultiIndex indexes names
indexes_names = df.index.names
df.reset_index().to_json('dump.json')
# return back MultiIndex structure:
loaded_df = pd.read_json('dump.json').set_index(indexes_names)
【讨论】:
如果你在一个系列中使用名称,它会生成一个只有 1 级的冻结集。如果你简单地执行以下操作,这将有效:pd.read_json('series.json').set_index(series.index)
【参考方案4】:
这是我对多索引熊猫数据帧进行编码/解码的简单脏修复,它似乎也适用于索引/列中的日期时间...未优化!
这里是 json 的编码器 - 我将数据帧、索引和列编码到 dict 中以创建 json
import json
import pandas as pd
def to_json_multiindex(df):
dfi = df.index.to_frame()
dfc = df.columns.to_frame()
d = dict(
df = df.to_json(),
di = dfi.to_json(),
dc = dfc.to_json()
)
return json.dumps(d)
同时这里是读取 json 字典并重新创建数据帧的解码器
def read_json_multiindex(j):
d = json.loads(j)
di=pd.read_json(d['di'])
if di.shape[1]>1:
di = pd.MultiIndex.from_frame(di)
else:
_name = di.columns[0]
di = di.index
di.name = _name
dc=pd.read_json(d['dc'])
if dc.shape[1]>1:
dc = pd.MultiIndex.from_frame(dc)
else:
_name = dc.columns[0]
dc = dc.index
dc.name = _name
df = pd.read_json(d['df']).values
return pd.DataFrame(
data=df,
index=di,
columns=dc,
)
这是对多索引列和索引的测试...似乎保留了数据框。几个问题 1) 可能效率低下,2) 似乎确实适用于多索引中的数据时间(但在它不是多索引时有效)
df = pd.DataFrame(
data = [[0,1,2],[2,3,4],[5,6,7]],
index = pd.MultiIndex.from_tuples(
(('aa','bb'),('aa','cc'),('bb','cc')
),
names=['AA','BB']),
columns = pd.MultiIndex.from_tuples(
(('XX','YY'),('XX','ZZ'),('YY','ZZ')
),
names=['YY','ZZ'])
)
j = to_json_multiindex(df)
d = read_json_multiindex(j)
【讨论】:
以上是关于熊猫读取 json 不适用于 MultiIndex的主要内容,如果未能解决你的问题,请参考以下文章