【问题标题】:How to generate n-level hierarchical JSON from pandas DataFrame?如何从 pandas DataFrame 生成 n 级分层 JSON?
【发布时间】:2018-02-22 15:05:43
【问题描述】:

有没有一种有效的方法来创建分层 JSON(n 级深),其中父值是键而不是变量标签?即:

{"2017-12-31":
    {"Junior":
        {"Electronics":
            {"A":
                {"sales": 0.440755
                }
            },
            {"B":
                {"sales": -3.230951
                }
            }
        }, ...etc...
    }, ...etc...
}, ...etc... 

1.我的测试数据框:

colIndex=pd.MultiIndex.from_product([['New York','Paris'],
                                     ['Electronics','Household'],
                                     ['A','B','C'],
                                     ['Junior','Senior']],
                               names=['City','Department','Team','Job Role'])

rowIndex=pd.date_range('25-12-2017',periods=12,freq='D')

df1=pd.DataFrame(np.random.randn(12, 24), index=rowIndex, columns=colIndex)
df1.index.name='Date'
df2=df1.resample('M').sum()
df3=df2.stack(level=0).groupby('Date').sum()


2。我正在进行的转换,因为它似乎是构建 JSON 的最合乎逻辑的结构:

df4=df3.stack(level=[0,1,2]).reset_index() \
    .set_index(['Date','Job Role','Department','Team']) \
    .sort_index()


3.到目前为止我的尝试

我遇到了这个very helpful SO question,它使用以下代码解决了一级嵌套问题:

j =(df.groupby(['ID','Location','Country','Latitude','Longitude'],as_index=False) \
    .apply(lambda x: x[['timestamp','tide']].to_dict('r'))\
    .reset_index()\
    .rename(columns={0:'Tide-Data'})\
    .to_json(orient='records'))

...但我找不到让嵌套.groupby()s 工作的方法:

j=(df.groupby('date', as_index=True).apply(
    lambda x: x.groupby('Job Role', as_index=True).apply(
        lambda x: x.groupby('Department', as_index=True).apply(
            lambda x: x.groupby('Team', as_index=True).to_dict())))  \
                .reset_index().rename(columns={0:'sales'}).to_json(orient='records'))

【问题讨论】:

  • 您能否以文本/CSV 格式发布示例数据集,以便我们复制和粘贴?
  • @MaxU - 我已经用我的输入虚拟 DataFrame 更新了问题的开头 - 谢谢!

标签: python json pandas dataframe


【解决方案1】:

您可以使用 itertuples 生成嵌套的dict,然后转储到json。为此,您需要将日期时间戳更改为string

df4=df3.stack(level=[0,1,2]).reset_index() 
df4['Date'] = df4['Date'].dt.strftime('%Y-%m-%d')
df4 = df4.set_index(['Date','Job Role','Department','Team']) \
    .sort_index()

创建嵌套字典

def nested_dict():
    return collections.defaultdict(nested_dict)
result = nested_dict()

使用itertuples 填充它

for row in df4.itertuples():
    result[row.Index[0]][row.Index[1]][row.Index[2]][row.Index[3]]['sales'] = row._1
    # print(row)

然后使用json 模块转储它。

import json
json.dumps(result)

'{“2017-12-31”:{“初级”:{“电子”:{“A”:{“销售”:-0.3947134370101142},“B”:{“销售”:-0.9873530754403204}, “C”:{“销售额”:-1.1182598058984508}},“家庭”:{“A”:{“销售额”:-1.1211850078098677},“B”:{“销售额”:2.0330914483907847},“C”:{”销售”:3.94762379718749}}},“高级”:{“电子”:{“A”:{“销售”:1.4528493451404196},“B”:{“销售”:-2.3277322345261005},“C”:{“销售” “:-2.8040263791743922}},“家庭”:{“A”:{“销售”:3.0972591929279663},“B”:{“销售”:9.884565742502392},“C”:{“销售”:2.9359830722457576}}}} ,“2018-01-31”:{“初级”:{“电子”:{“A”:{“销售”:-1.3580300149125217},“B”:{“销售”:1.414665000013205},“C”:{ “销售”:-1.432795129108244}},“家庭”:{“A”:{“销售”:2.7783259569115346},“B”:{“销售”:2.717700275321333},“C”:{“销售”:1.4358377416259644}} },“高级”:{“电子”:{“A”:{“销售”:2.8981726774941485},“B”:{“销售”:12.022897003654117},“C”:{“销售”:0.01776855733076088}},“家庭”:{“A”:{“销售”:-3.3421637766130 92},“B”:{“销售额”:-5.283208386572307},“C”:{“销售额”:2.942580121975619}}}}}'

【讨论】:

【解决方案2】:

我遇到了这个问题,并对 OP 设置的复杂性感到困惑。这是一个最小的示例和解决方案(基于@Maarten Fabré 提供的答案)。

import collections
import pandas as pd

# build init DF
x = ['a', 'a']
y = ['b', 'c']
z = [['d'], ['e', 'f']]
df = pd.DataFrame(list(zip(x, y, z)), columns=['x', 'y', 'z'])

#    x  y       z
# 0  a  b     [d]
# 1  a  c  [e, f]

设置常规、平面、索引,然后将其设为多索引

# set flat index
df = df.set_index(['x', 'y'])

# set up multi index
df = df.reindex(pd.MultiIndex.from_tuples(zip(x, y)))      

#           z
# a b     [d]
#   c  [e, f]

然后初始化一个嵌套字典,逐项填写

nested_dict = collections.defaultdict(dict)

for keys, value in df.z.iteritems():
    nested_dict[keys[0]][keys[1]] = value

# defaultdict(dict, {'a': {'b': ['d'], 'c': ['e', 'f']}})

此时你可以 JSON 转储它,等等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-05
    • 2015-12-17
    • 1970-01-01
    • 2020-07-31
    • 2021-03-19
    • 2017-03-25
    • 2020-09-21
    相关资源
    最近更新 更多