使用python将Excel中的按列JSON数据转换为层次结构 总体目标

使用python将Excel中的按列JSON数据转换为层次结构 总体目标,python,json,excel,pandas,Python,Json,Excel,Pandas,我的总体目标是将Excel文件中的输入转换为文本文件(Stata.do文件),以执行一组数据协调任务,这些任务具有大致相同的结构,但由于数据的特殊性(国家调查),需要单独处理。协调将由不同的人员执行,Excel确保人员使用相同的结构。我的策略是读取JSON结构中的Excel文件,使用此结构写入do文件 我请求帮助的任务 我现在试图解决的问题是如何从JSON从Excel读取时的列结构转换为层次结构。我希望用户拥有的Excel文件具有块和块内任务的结构,以及执行任务所需的特定命令(一行或多行)。下图

我的总体目标是将Excel文件中的输入转换为文本文件(Stata.do文件),以执行一组数据协调任务,这些任务具有大致相同的结构,但由于数据的特殊性(国家调查),需要单独处理。协调将由不同的人员执行,Excel确保人员使用相同的结构。我的策略是读取JSON结构中的Excel文件,使用此结构写入do文件

我请求帮助的任务 我现在试图解决的问题是如何从JSON从Excel读取时的列结构转换为层次结构。我希望用户拥有的Excel文件具有块和块内任务的结构,以及执行任务所需的特定命令(一行或多行)。下图是Excel文档的一个示例:

最终目标是生成如下文本文件:

* A 

* A1    
Command for A1
        
* A2    
Command for A2 (1)
Command for A2 (2)
        
* B 

* B1    
Command for B1 (1)
Command for B1 (2)
Command for B1 (3)
        
*B2 
Command for B2 (1)
Command for B2 (2)
import pandas as pd
import json
from collections import defaultdict

path = "Some Path/test.xlsx"
df = pd.read_excel(path,
                   engine='openpyxl',
                   # header=None, names=['Block', 'Task', 'Code']  # only if your file has no headers
                   )

df.dropna(inplace=True, axis=0, how='all')
df.fillna(method='ffill', inplace=True, axis=0)
df = df.set_index(['Block', 'Task'])

nested_dict = defaultdict(lambda : defaultdict(list))

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

json_str = json.dumps(nested_dict, indent=4, sort_keys=True)
print(json_str)
我使用Python阅读以下代码:

path = "Some Path/test.xlsx"
import pandas
import json

x = pandas.read_excel(path, sheet_name='Sheet')
json_str = x.to_json()
如前所述,这将产生JSON的列结构,如下所示:

* A 

* A1    
Command for A1
        
* A2    
Command for A2 (1)
Command for A2 (2)
        
* B 

* B1    
Command for B1 (1)
Command for B1 (2)
Command for B1 (3)
        
*B2 
Command for B2 (1)
Command for B2 (2)
import pandas as pd
import json
from collections import defaultdict

path = "Some Path/test.xlsx"
df = pd.read_excel(path,
                   engine='openpyxl',
                   # header=None, names=['Block', 'Task', 'Code']  # only if your file has no headers
                   )

df.dropna(inplace=True, axis=0, how='all')
df.fillna(method='ffill', inplace=True, axis=0)
df = df.set_index(['Block', 'Task'])

nested_dict = defaultdict(lambda : defaultdict(list))

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

json_str = json.dumps(nested_dict, indent=4, sort_keys=True)
print(json_str)

我正在努力将其转换为代码自然具有的层次结构。我希望的输出是以下形式的JSON对象:

如果有一种更聪明的方法来实现总体目标,我很高兴听到它,但我认为这种翻译是构建信息结构的必要步骤

下面是生成JSON对象以实现再现性的代码

# Column-wise object
'{"Block":{"0":"* A","1":null,"2":null,"3":null,"4":null,"5":null,"6":"* B","7":null,"8":null,"9":null,"10":null,"11":null},"Task":{"0":"* A1","1":null,"2":null,"3":"* A2","4":null,"5":null,"6":"* B1","7":null,"8":null,"9":null,"10":"*B2","11":null},"Code":{"0":"Command for A1","1":null,"2":null,"3":"Command for A2 (1)","4":"Command for A2 (2)","5":null,"6":"Command for B1 (1)","7":"Command for B1 (2)","8":"Command for B1 (3)","9":null,"10":"Command for B2 (1)","11":"Command for B2 (2)"}}'

# Hierarchical object
'{"* A": {"* A1": ["Command for A1"], "* A2": ["Command for A2 (1)", "Command for A2 (2)"] }, "* B" : {"* B1" : ["Command for B1 (1)", "Command for B1 (2)", "Command for B1 (3)"], "* B2" : ["Command for B2 (1)", "Command for B2 (2)"]}}'

您可以这样做:

* A 

* A1    
Command for A1
        
* A2    
Command for A2 (1)
Command for A2 (2)
        
* B 

* B1    
Command for B1 (1)
Command for B1 (2)
Command for B1 (3)
        
*B2 
Command for B2 (1)
Command for B2 (2)
import pandas as pd
import json
from collections import defaultdict

path = "Some Path/test.xlsx"
df = pd.read_excel(path,
                   engine='openpyxl',
                   # header=None, names=['Block', 'Task', 'Code']  # only if your file has no headers
                   )

df.dropna(inplace=True, axis=0, how='all')
df.fillna(method='ffill', inplace=True, axis=0)
df = df.set_index(['Block', 'Task'])

nested_dict = defaultdict(lambda : defaultdict(list))

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

json_str = json.dumps(nested_dict, indent=4, sort_keys=True)
print(json_str)
输出:

{
    "* A": {
        "* A1": [
            "Command for A1"
        ],
        "* A2": [
            "Command for A2 (1)",
            "Command for A2 (2)"
        ]
    },
    "* B": {
        "* B1": [
            "Command for B1 (1)",
            "Command for B1 (2)",
            "Command for B1 (3)"
        ],
        "* B2": [
            "Command for B2 (1)",
            "Command for B2 (2)"
        ]
    }
}