Pandas 数据帧处理 Pandas 表中 Json 内的嵌套列表以用于后续 Numpy 数组

问题描述 投票:0回答:1

所以我一直在为我正在开发的一个小项目使用块设备的 json.loads() 。目前,我正在尝试将 json 数据输入 Pandas 数据帧,然后将该数据帧转换为 numpy 数组,以便由名为 CurseXcel 的第三方项目处理,但我离题了。

我目前遇到的问题是如何正确处理 json 数据字典列表中的子项。我能够计算出的代码本质上是

def return_pandas():
    process = subprocess.run("lsblk --json -o NAME,SIZE,UUID,MOUNTPOINT,PATH,FSTYPE ".split(), capture_output=True, text=True)
    data = json.loads(process.stdout)
    return pd.json_normalize(data['blockdevices'])

然后

json_pandas = return_pandas()

返回

  name   size  uuid mountpoint      path fstype                                           children
0  sda    25G  None       None  /dev/sda   None                                                NaN
1  sdb    25G  None       None  /dev/sdb   None  [{'name': 'sdb1', 'size': '512M', 'uuid': '008...
2  sr0  1024M  None       None  /dev/sr0   None                                                NaN

作为一张桌子。 同样,我遇到的麻烦是获取所述 json 和 pandas 数据帧表中的“子项”列表,以便可能与常规设备一起列出,或者在包含名称大小 uuid 等的子项列中以更规范化的方式列出。这将涉及可能使用递归来展平所有数据或其他内容。

Numpy 数据看起来像这样

[['sda' '25G' None None '/dev/sda' None nan]
 ['sdb' '25G' None None '/dev/sdb' None
  list([{'name': 'sdb1', 'size': '512M', 'uuid': '0087-DF28', 'mountpoint': '/boot/efi', 'path': '/dev/sdb1', 'fstype': 'vfat'}, {'name': 'sdb2', 'size': '488M', 'uuid': 'bd51147c-8f8c-4d3a-afde-4ebf67ae4558', 'mountpoint': '/boot', 'path': '/dev/sdb2', 'fstype': 'ext2'}, {'name': 'sdb3', 'size': '24G', 'uuid': 'd07d17bf-ebbd-491a-b57c-f9d43b7e6be5', 'mountpoint': None, 'path': '/dev/sdb3', 'fstype': 'crypto_LUKS', 'children': [{'name': 'sda3_crypt', 'size': '24G', 'uuid': '3NbbDi-BtQ4-PXzK-NVBO-cR2d-aLzZ-pzh0A5', 'mountpoint': None, 'path': '/dev/mapper/sda3_crypt', 'fstype': 'LVM2_member', 'children': [{'name': 'kali--vg-root', 'size': '23G', 'uuid': '6bc26692-9b22-4d38-b1c0-53e99326e9d5', 'mountpoint': '/', 'path': '/dev/mapper/kali--vg-root', 'fstype': 'ext4'}, {'name': 'kali--vg-swap_1', 'size': '980M', 'uuid': '3eb8e4cc-56bb-4b5b-b2a8-bc7ac016df67', 'mountpoint': '[SWAP]', 'path': '/dev/mapper/kali--vg-swap_1', 'fstype': 'swap'}]}]}])]
 ['sr0' '1024M' None None '/dev/sr0' None nan]]

如果我可以在将表渲染为 numpy 数组后获得该“列表”,因为它本身是未嵌套的,那就太好了。我再次不知所措,但我确信我错过了一些简单的事情。

这可能涉及展平为一维数组,但我仍然希望保持使用 numpyarrays 的能力。我考虑过使用递归,但具体不知道如何在不重新创建整个结构的情况下获取嵌套列表,也不知道适用于嵌套列表的条件语句。

每个请求的数据输出

{'blockdevices': [{'name': 'sda', 'size': '25G', 'uuid': None, 'mountpoint': None, 'path': '/dev/sda', 'fstype': None}, {'name': 'sdb', 'size': '25G', 'uuid': None, 'mountpoint': None, 'path': '/dev/sdb', 'fstype': None, 'children': [{'name': 'sdb1', 'size': '512M', 'uuid': '0087-DF28', 'mountpoint': '/boot/efi', 'path': '/dev/sdb1', 'fstype': 'vfat'}, {'name': 'sdb2', 'size': '488M', 'uuid': 'bd51147c-8f8c-4d3a-afde-4ebf67ae4558', 'mountpoint': '/boot', 'path': '/dev/sdb2', 'fstype': 'ext2'}, {'name': 'sdb3', 'size': '24G', 'uuid': 'd07d17bf-ebbd-491a-b57c-f9d43b7e6be5', 'mountpoint': None, 'path': '/dev/sdb3', 'fstype': 'crypto_LUKS', 'children': [{'name': 'sda3_crypt', 'size': '24G', 'uuid': '3NbbDi-BtQ4-PXzK-NVBO-cR2d-aLzZ-pzh0A5', 'mountpoint': None, 'path': '/dev/mapper/sda3_crypt', 'fstype': 'LVM2_member', 'children': [{'name': 'kali--vg-root', 'size': '23G', 'uuid': '6bc26692-9b22-4d38-b1c0-53e99326e9d5', 'mountpoint': '/', 'path': '/dev/mapper/kali--vg-root', 'fstype': 'ext4'}, {'name': 'kali--vg-swap_1', 'size': '980M', 'uuid': '3eb8e4cc-56bb-4b5b-b2a8-bc7ac016df67', 'mountpoint': '[SWAP]', 'path': '/dev/mapper/kali--vg-swap_1', 'fstype': 'swap'}]}]}]}, {'name': 'sr0', 'size': '1024M', 'uuid': None, 'mountpoint': None, 'path': '/dev/sr0', 'fstype': None}]}
                                                                                                                                                                     
python pandas dataframe numpy numpy-ndarray
1个回答
0
投票

这是您期望的输出吗?

代码:

df = pd.json_normalize(data=data.get("blockdevices")).explode(column="children")
df = (pd
      .concat(objs=[df, df.children.apply(func=pd.Series)], axis=1)
      .drop(columns=0)
      .fillna("")
      .drop(columns="children").reset_index(drop=True)
      )
print(df)

结果:

  name   size uuid mountpoint      path fstype  name  size                                  uuid mountpoint       path       fstype
0  sda    25G                  /dev/sda                                                                                            
1  sdb    25G                  /dev/sdb         sdb1  512M                             0087-DF28  /boot/efi  /dev/sdb1         vfat
2  sdb    25G                  /dev/sdb         sdb2  488M  bd51147c-8f8c-4d3a-afde-4ebf67ae4558      /boot  /dev/sdb2         ext2
3  sdb    25G                  /dev/sdb         sdb3   24G  d07d17bf-ebbd-491a-b57c-f9d43b7e6be5             /dev/sdb3  crypto_LUKS
4  sr0  1024M                  /dev/sr0      

                                                                                  
© www.soinside.com 2019 - 2024. All rights reserved.