将Python多重嵌套字典转换为Pandas数据框布尔表

4

我希望能获得有关如何将Python多级嵌套的字典(来自JSON)清晰地转换为数据框布尔表的任何建议。

规则:

  • 只记录True。 如果为空,则为False。
  • 列表可能是N长度
  • 组可能是N长度
  • bool可能是N类型

示例输入:

{1:{'group_a':{'bool_a':True,
               'bool_b':True,
               'bool_n':True},
    'group_n':{'bool_b':True,
               'bool_n':True}
   },
 2:{'group_a':{'bool_a':True,
               'bool_b':True,
               'bool_n':True},
    'group_n':{'bool_b':True,
               'bool_n':True}
   },
'n':{'group_a':{'bool_a':True,
                'bool_c':True},
     'group_n':{'bool_b':True}
   },
}

期望输出:

   Ga_Ba, Ga_Bb, Ga_Bc, Ga_Bn, Gn_Ba, Gn_Bb, ... Gn_Bn....
1   True   True  False  True   False   True       True
2   True   True  False  True   False   True       True
n   True   False True   False  False   False      False
...

想法?速度和简洁度得分更高。我有一个解决方案,但我正在寻找比我现在混乱的for循环更优雅的东西。也可以考虑使用替代数据结构。
4个回答

3

简单易懂的方法 #1

s = pd.DataFrame.from_dict(data, orient='index').stack()

pd.json_normalize(s).set_index(s.index) \
  .stack().unstack([1, 2], fill_value=False) \
  .sort_index(axis=1)

  group_a                      group_n       
   bool_a bool_b bool_c bool_n  bool_b bool_n
1    True   True  False   True    True   True
2    True   True  False   True    True   True
3    True  False   True  False    True  False

直接理解

pd.DataFrame.from_dict({
    k0: {
            f'G{k1.split("_")[1]}_B{k2.split("_")[1]}': val
            for k1, d1 in d0.items()
            for k2, val in d1.items()
        }
    for k0, d0 in data.items()
}, orient='index').fillna(False)

   Ga_Ba  Ga_Bb  Ga_Bn  Gn_Bb  Gn_Bn  Ga_Bc
1   True   True   True   True   True  False
2   True   True   True   True   True  False
3   True  False  False   True  False   True

3
你可以使用字典解析和concat函数:
import pandas as pd

values = {
    "1": {
        "group_a": {"bool_a": True, "bool_b": True, "bool_n": True},
        "group_n": {"bool_b": True, "bool_n": True},
    },
    "2": {
        "group_a": {"bool_a": True, "bool_b": True, "bool_n": True},
        "group_n": {"bool_b": True, "bool_n": True},
    },
    "n": {"group_a": {"bool_a": True, "bool_c": True}, "group_n": {"bool_b": True}},
}
stacked_values = {k: pd.DataFrame(v).stack() for k, v in values.items()}
df = (
    pd.concat(stacked_values, axis=1)
    .T.fillna(False)
    .swaplevel(axis=1)  # optional
    .sort_index(axis=1)
)

输出:

  group_a                      group_n       
   bool_a bool_b bool_c bool_n  bool_b bool_n
1    True   True  False   True    True   True
2    True   True  False   True    True   True
n    True  False   True  False    True  False

1
@Bill 为什么要使用中间变量? ;) - mozway
1
中间值并非必需,但它可以帮助说明解决方案中正在发生的中间转换。操作者应该随心所欲地内联此内容 :) 我编辑的真正目的是为您的解决方案包括一个完全可执行的示例,这一点我很喜欢。 - Bill DeRose

1

尝试:

df = pd.DataFrame(
    [
        {f"{k}_{kk}": vv for k, v in d.items() for kk, vv in v.items()}
        for d in data.values()
    ],
    index=data,
).fillna(False)

print(df)

输出:

   group_a_bool_a  group_a_bool_b  group_a_bool_n  group_n_bool_b  group_n_bool_n  group_a_bool_c
1            True            True            True            True            True           False
2            True            True            True            True            True           False
n            True           False           False            True           False            True

0
尝试使用数据框架的透视表。
dct={1:{'group_a':{'bool_a':True,
               'bool_b':True,
               'bool_n':True},
    'group_n':{'bool_b':True,
               'bool_n':True}
   },
 2:{'group_a':{'bool_a':True,
               'bool_b':True,
               'bool_n':True},
    'group_n':{'bool_b':True,
               'bool_n':True}
   },
'n':{'group_a':{'bool_a':True,
                'bool_c':True},
     'group_n':{'bool_b':True}
   },
}
df=pd.DataFrame.from_dict(dct, orient='index')
df=df.stack()
lst=[]
for k,vals in df.items():
    for index,item in vals.items():
        lst.append((k[0],k[1],index,item))
        
df=pd.DataFrame(lst,columns=['col1','col2','col3','col4'])
#print(df)
fp=df.pivot_table(index='col1',columns=['col2','col3'],values='col4', aggfunc=np.any).fillna(False)
print(fp)

输出:

col2 group_a                      group_n       
col3  bool_a bool_b bool_c bool_n  bool_b bool_n
col1                                            
1       True   True  False   True    True   True
2       True   True  False   True    True   True
n       True  False   True  False    True  False

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接