首页 > 解决方案 > 来自字典列表的python数据框,其中一些值作为列表

问题描述

我对下面提供的内容有类似格式的输入,我正在尝试将其转换为 python DataFrame

my_input = [
{'comp_id': '111', 'name': 'A-Name', 'brnch_id': ['BR-AA1', 'BR-AA2']},
{'comp_id': '222', 'name': 'B-Name', 'brnch_id': ['BR-BB1', 'BR-BB2', 'BR-BB3']},
{'comp_id': '333', 'name': 'C-Name', 'brnch_id': None}
]

所需的输出应该是:

        comp_id     name        brnch_id
        -------     ------      --------
        111         A-Name      BR-AA1
        111         A-Name      BR-AA2
        222         B-Name      BR-BB1
        222         B-Name      BR-BB2
        222         B-Name      BR-BB3
        333         C-Name          

有什么建议么?

explode 方法似乎很有用,但我应该更加努力地解决我的问题,并建议数据输入可能有不止一个需要扩展的列,所以这是一个修改后的挑战:

[
{'comp_id': '111', 'name': 'A-Name', 'brnch_id': ['BR-1111', 'BR-1112'], 'brnch_name': ['AA1','AA2']},
{'comp_id': '222', 'name': 'B-Name', 'brnch_id': ['BR-2221', 'BR-2222', 'BR-2223'], 'brnch_name': ['BB1','BB2','BB3']},
{'comp_id': '333', 'name': 'C-Name', 'brnch_id': None, 'brnch_name': None}
]

所需的输出如下:

        comp_id     name        brnch_id    brnch_name
        -------     ------      --------    ----------
        111         A-Name      BR-1111     AAA1
        111         A-Name      BR-1112     AAA2
        222         B-Name      BR-2221     BBB1
        222         B-Name      BR-2222     BBB2
        222         B-Name      BR-2223     BBB3
        333         C-Name  

期望每个 comp_id 应该有一个名称,如果分支存在,它应该有一个 id (brnch_id) 和 brnch_name

添加第二个 .explode 不会产生所需的输出。

   comp_id    name brnch_id brnch_name
0      111  A-Name  BR-1111        AA1
1      111  A-Name  BR-1111        AA2
2      111  A-Name  BR-1112        AA1
3      111  A-Name  BR-1112        AA2
4      222  B-Name  BR-2221        BB1
5      222  B-Name  BR-2221        BB2
6      222  B-Name  BR-2221        BB3
7      222  B-Name  BR-2222        BB1
8      222  B-Name  BR-2222        BB2
9      222  B-Name  BR-2222        BB3
10     222  B-Name  BR-2223        BB1
11     222  B-Name  BR-2223        BB2
12     222  B-Name  BR-2223        BB3
13     333  C-Name     None       None

Brnch_name 正在为每个 brnch_id 展开。所以 brnch_id = BR-1111 显示为具有两个 brnch_name:AA1 和 AA2。

标签: pythondataframe

解决方案


这将做:

df=pd.DataFrame(my_input)
df=df.explode('brnch_id').reset_index(drop=True)

输出:

  comp_id    name brnch_id
0     111  A-Name   BR-AA1
1     111  A-Name   BR-AA2
2     222  B-Name   BR-BB1
3     222  B-Name   BR-BB2
4     222  B-Name   BR-BB3
5     333  C-Name     None

编辑您的扩展示例:

from itertools import zip_longest

df=pd.DataFrame(my_input)
df["x"]=list(zip(df['brnch_id'].fillna(''), df['brnch_name'].fillna('')))

df["x"]=df["x"].apply(lambda x: list(zip_longest(*x)))
df=df.explode('x')
mask=~df['x'].isna()
df.loc[mask, 'brnch_id']=df.loc[mask, 'x'].str[0]
df.loc[mask, 'brnch_name']=df.loc[mask, 'x'].str[1]
df=df.drop('x', axis=1).reset_index(drop=True)

输出:

>>> df.iloc[:, -2:]

  brnch_id brnch_name
0  BR-1111        AA1
1  BR-1112        AA2
2  BR-2221        BB1
3  BR-2222        BB2
4  BR-2223        BB3
5     None       None

推荐阅读