Python 将具有两个不同级别数据的dataframe转换为嵌套字典

Python 将具有两个不同级别数据的dataframe转换为嵌套字典,python,pandas,dictionary,Python,Pandas,Dictionary,正如标题中提到的,我有两个不同级别的数据,第一个级别是较高级别和较低级别,较高级别的数据有多个来自附在其上的较低数据的记录(即1:n关系)。我将两个数据帧连接在一起,创建了一个包含两个级别数据的数据帧,如下所示: id col1 col2 col3 col4 col5 col6 1 5 10 5 15 9 6 1 5 10 5 14 15 8 2

正如标题中提到的,我有两个不同级别的数据,第一个级别是较高级别和较低级别,较高级别的数据有多个来自附在其上的较低数据的记录(即1:n关系)。我将两个数据帧连接在一起,创建了一个包含两个级别数据的数据帧,如下所示:

id  col1    col2    col3    col4    col5    col6
1   5       10      5       15      9       6
1   5       10      5       14      15      8
2   8       2       5       6       13      2
2   8       2       5       9       18      6
3   1       4       10      4       5       17
3   1       4       10      9       16      17
前四列(id、col1、col2、col3)与较高级别的数据相关,而后三列(col4、col5和col6)则来自较低级别的数据。这里还可以使用1:n关系,其中前四列在多行上具有相同的值,而后三列具有唯一的值。我想将此数据帧转换为以下格式的python字典:

{
    "id": 1,
    "data": {
        "col1": 5,
        "col2": 10,
        "col3": 5,
        "low_level_data": [
            {"col4": 15, "col5": 9, "col6": 6},
            {"col4": 14, "col5": 15, "col6": 8}
        ]
    },
    "id": 2,
    "data": {
        "col1": 8,
        "col2": 2,
        "col3": 5,
        "low_level_data": [
            {"col4": 6, "col5": 13, "col6": 2},
            {"col4": 9, "col5": 18, "col6": 6}
        ]
    },
    "id": 3,
    "data": {
        "col1": 1,
        "col2": 4,
        "col3": 10,
        "lower_level_data": [
            {"col4": 4, "col5": 5, "col6": 17},
            {"col4": 9, "col5": 16, "col6": 17}
        ]
    }
}
我知道我需要使用
to_dict()
方法,但我不确定如何确保输出将非唯一列作为字典中的键,同时在下面级别的列表中也包含较低级别的列。我发现的其他答案似乎没有相同的数据结构,我自己也无法得到想要的输出。我尝试了以下方法,但不幸的是没有给出想要的输出

df.groupby(["id", "col1", "col2", "col3"]).agg(lambda x: x.tolist()).to_dict("index")

# output
{('1', '5', '10', '5'): {'col4': ['15', '14'],
  'col5': ['9', '15'],
  'col6': ['6', '8']},
 ('2', '8', '2', '5'): {'col4': ['6', '9'],
  'col5': ['13', '18'],
  'col6': ['2', '6']},
 ('3', '1', '4', '10'): {'col4': ['4', '9'],
  'col5': ['5', '16'],
  'col6': ['17', '17']}}
示例数据帧可按如下方式创建:

data = """id    col1    col2    col3    col4    col5    col6
1   5   10  5   15  9   6
1   5   10  5   14  15  8
2   8   2   5   6   13  2
2   8   2   5   9   18  6
3   1   4   10  4   5   17
3   1   4   10  9   16  17"""
data = [x.split("\t") for x in data.split("\n")]
df = pd.DataFrame(data[1:], columns=data[0])

我认为标准的
pandas
方法并不适合这种情况。我只需在data.frame上迭代以构建所需的输出

df.groupby(["id", "col1", "col2", "col3"]).agg(lambda x: x.tolist()).to_dict("index")

# output
{('1', '5', '10', '5'): {'col4': ['15', '14'],
  'col5': ['9', '15'],
  'col6': ['6', '8']},
 ('2', '8', '2', '5'): {'col4': ['6', '9'],
  'col5': ['13', '18'],
  'col6': ['2', '6']},
 ('3', '1', '4', '10'): {'col4': ['4', '9'],
  'col5': ['5', '16'],
  'col6': ['17', '17']}}
我想你的输出应该是一个目录,而不是一个目录。以下是解决方案的外观:

result = []
for id in df.id.unique():
    tmp_df = df.loc[df.id == id]
    tmp_res = {
        "id": tmp_df["id"].iloc[0],
        "data": {
            "col1": tmp_df["col1"].iloc[0],
            "col2": tmp_df["col2"].iloc[0],
            "col3": tmp_df["col3"].iloc[0],
            "low_level_data": tmp_df.loc[:, ["col4", "col5", "col6"]].to_dict("record")
        }
    }
    result.append(tmp_res)


正如Quang和Alex提到的,我提供的预期输出不是有效的python字典,而是字典列表。虽然Alex的答案有效并给出了预期的结果,但我还是设法自己找到了答案,使用了多种
groupby
apply
方法,我觉得这些方法更灵活一些

(
    df
    .groupby(["id", "col1", "col2", "col3"])["col4", "col5", "col6"]
    .apply(lambda x: x.to_dict("r"))
    .rename("low_level_data")
    .reset_index()
    .groupby("id")["col1", "col2", "col3", "low_level_data"]
    .apply(lambda x: x.to_dict("r")[0])
    .rename("data")
    .reset_index()
    .to_dict("r")
)

# output
[{'id': '1',
  'data': {'col1': '5',
   'col2': '10',
   'col3': '5',
   'low_level_data': [{'col4': '15', 'col5': '9', 'col6': '6'},
    {'col4': '14', 'col5': '15', 'col6': '8'}]}},
 {'id': '2',
  'data': {'col1': '8',
   'col2': '2',
   'col3': '5',
   'low_level_data': [{'col4': '6', 'col5': '13', 'col6': '2'},
    {'col4': '9', 'col5': '18', 'col6': '6'}]}},
 {'id': '3',
  'data': {'col1': '1',
   'col2': '4',
   'col3': '10',
   'low_level_data': [{'col4': '4', 'col5': '5', 'col6': '17'},
    {'col4': '9', 'col5': '16', 'col6': '17'}]}}]

您的预期输出不是有效的Python字典:重复的键
id
,和
data
等。