Может кто-нибудь объяснить, что я делаю wring при преобразовании этого фрейма данных в dictionary в Python

#python #pandas #dataframe #dictionary #nested

#python #pandas #фрейм данных #словарь #вложенный

Вопрос:

 index      print_type_solid      print_type_floral  cluster
     A           10                     10            2
     B           20                     20            2
     A           10                     10            3
     B           20                     20            3
     C           25                     30            3

  

Может ли кто-нибудь помочь мне преобразовать приведенный выше фрейм данных в следующий вложенный словарь, где кластер становится основным ключом, а ключ print_type_x — ключом, а затем значениями, как показано в ожидаемом выводе ниже?

  {  
 "2" :{
        "print_type_solid" : {
          "A": 10,
          "B": 20
                            },
        "print_type_floral" : {
            "A": 10,
            "B": 20
                             }
        },

"3" :{
        "print_type_solid" : {
          "A": 10,
          "B": 20,
          "C": 25,
                            },
        "print_type_floral" : {
            "A": 10,
            "B": 20,
            "C": 30,
                             }
        }

}
  

Я попробовал это :

 from collections import defaultdict
d = defaultdict()
d2={}


for k1, s in dct.items():
    for k2, v in s.items():
        for k3, r in v.items():
            d.setdefault(k3, {})[k2] = r

    d2[k1]=d
  

Но я получаю это :

  {  
 "2" :{
        "print_type_solid" : {
          "A": 10,
          "B": 20,
          "C": 25
                            },
        "print_type_floral" : {
            "A": 10,
            "B": 20,
            "C": 30
                             }
        },

"3" :{
        "print_type_solid" : {
          "A": 10,
          "B": 20,
          "C": 25,
                            },
        "print_type_floral" : {
            "A": 10,
            "B": 20,
            "C": 30,
                             }
        }

}
  

И это неправильно, потому что я получаю C также в словаре для кластера 2.

Комментарии:

1. что вы пытаетесь сделать?

2. почему вы используете defaultdict и setdefault? почему не defaultdict (dict)? вы понимаете, как работают defaultdicts?

Ответ №1:

Вы можете использовать df.iterrows() для итерации вашего фрейма данных по строкам. Для создания словаря вы можете использовать это:

 import pandas as pd

df = pd.DataFrame( {"index":list("ABABC"),
                    "print_type_solid":[10,20,10,20,25],
                    "print_type_floral":[10,20,10,20,30],
                    "cluster":[2,2,3,3,3] }) 

print(df)

d = {}
pts = "print_type_solid"
ptf = "print_type_floral"

for idx, row in df.iterrows():
    key = d.setdefault(row["cluster"],{})

    key_pts = key.setdefault(pts,{})
    key_pts[row["index"]] = row[pts]

    key_ptf = key.setdefault(ptf,{})
    key_ptf[row["index"]] = row[ptf]


from pprint import pprint
pprint(d)
  

Вывод:

 # df
  index  print_type_solid  print_type_floral  cluster
0     A                10                 10        2
1     B                20                 20        2
2     A                10                 10        3
3     B                20                 20        3
4     C                25                 30        3

# dict
{2: {'print_type_floral': {'A': 10, 'B': 20},
     'print_type_solid':  {'A': 10, 'B': 20}},
 3: {'print_type_floral': {'A': 10, 'B': 20, 'C': 30},
     'print_type_solid':  {'A': 10, 'B': 20, 'C': 25}}}
  

Вы также могли бы использовать collections.defaultdict — но для этих нескольких точек данных это не требуется.