2

我有一个包含姓名和部门的数据框。所有这些名称可以映射到 4 个不同的部门(部门 A、B、C 和 D)。例如,每个名称都必须映射到部门 A、B、C、D。在初始数据中,每个名称仅映射到一个部门。在最终数据集中,每个名称映射到四个不同的部门。我需要一种方法为每个名称插入 3 个额外的行,并为它们添加 3 个其他部门。

例子:

初始数据:

Name Department
Joe  A
Ellen A
Zach  A

最终数据:

Name Department
Joe  A
Joe  B
Joe  C
Joe  D
Ellen A
Ellen B
Ellen C
Ellen D
Zach  A
Zach  B
Zach  C
Zach  D

我知道这可以在某种 for 循环中完成,但我是 Pandas 的新手,任何帮助将不胜感激。

4

4 回答 4

2

您可以尝试将所有部门作为列表分配给每个名称,然后.explode

df = df.assign(Department=[["A", "B", "C", "D"]] * len(df)).explode(
    "Department"
)
print(df)

印刷:

    Name Department
0    Joe          A
0    Joe          B
0    Joe          C
0    Joe          D
1  Ellen          A
1  Ellen          B
1  Ellen          C
1  Ellen          D
2   Zach          A
2   Zach          B
2   Zach          C
2   Zach          D
于 2021-07-18T22:19:54.647 回答
2

假设只product需要 of 值itertools.productpandas函数的开销要少得多:

from itertools import product

import pandas as pd

df = pd.DataFrame({'Name': ['Joe', 'Ellen', 'Zach'],
                   'Department': ['A', 'A', 'A']})

根据名称计算新的 DataFrame unique

df = pd.DataFrame(product(df['Name'].unique(),
                          ['A', 'B', 'C', 'D']),
                  columns=df.columns)

df

     Name Department
0     Joe          A
1     Joe          B
2     Joe          C
3     Joe          D
4   Ellen          A
5   Ellen          B
6   Ellen          C
7   Ellen          D
8    Zach          A
9    Zach          B
10   Zach          C
11   Zach          D
于 2021-07-18T22:44:06.837 回答
1

另一种方法使用pandas.DataFrame.groupby

>>> departments = ['A', 'B', 'C', 'D']
>>> df.groupby('Name').apply(lambda _, L=departments: L).explode().to_frame('Department')
      Department
Name            
Ellen          A
Ellen          B
Ellen          C
Ellen          D
Joe            A
Joe            B
Joe            C
Joe            D
Zach           A
Zach           B
Zach           C
Zach           D

或者pd.Series.reset_index有一个name论点:在这样的配置中方便:

>>> df.groupby('Name').apply(lambda _, L=departments: L).explode().reset_index(name='Department')
     Name Department
0   Ellen          A
1   Ellen          B
2   Ellen          C
3   Ellen          D
4     Joe          A
5     Joe          B
6     Joe          C
7     Joe          D
8    Zach          A
9    Zach          B
10   Zach          C
11   Zach          D
于 2021-07-18T22:32:40.393 回答
0

我们的确是merge

out = df.merge(pd.DataFrame({'New Dept':list('ABCD')}),how='cross')
Out[373]: 
     Name Department New Dept
0     Joe          A        A
1     Joe          A        B
2     Joe          A        C
3     Joe          A        D
4   Ellen          A        A
5   Ellen          A        B
6   Ellen          A        C
7   Ellen          A        D
8    Zach          A        A
9    Zach          A        B
10   Zach          A        C
11   Zach          A        D
于 2021-07-19T02:32:02.113 回答