熊猫:根据组聚合添加新行

时间:2019-12-02 19:42:12

标签: python pandas

请帮助!

共有5个拒绝代码:EL1,EL2,EL3,EL4和EL5。我想添加新行,以便每个ID始终具有5个拒绝代码。

这是我原来的DF:

+----+-------------+-----+
| ID | Reject Code | QTY |
+----+-------------+-----+
| A  | EL1         |   7 |
| A  | EL2         |   2 |
| A  | EL3         |  33 |
| B  | EL1         |   7 |
| B  | EL2         |   1 |
| B  | EL3         |   7 |
| B  | EL4         |  36 |
| B  | EL5         |   5 |
| C  | EL1         |   3 |
| C  | EL2         |  32 |
+----+-------------+-----+

ID B具有所有拒绝代码,因此我们无需为此添加任何行。

ID A仅具有EL1,EL2和EL3,那么我如何追加2个新行并将EL4和EL5设置为0 QTY?

与ID C相同,我需要追加3行,EL3,EL4和EL5吗?

我想输出为:

+----+-------------+-----+
| ID | Reject Code | QTY |
+----+-------------+-----+
| A  | EL1         |   7 |
| A  | EL2         |   2 |
| A  | EL3         |  33 |
| A  | EL4         |   0 |
| A  | EL5         |   0 |
| B  | EL1         |   7 |
| B  | EL2         |   1 |
| B  | EL3         |   7 |
| B  | EL4         |  36 |
| B  | EL5         |   5 |
| C  | EL1         |   3 |
| C  | EL2         |  32 |
| C  | EL3         |   0 |
| C  | EL4         |   0 |
| C  | EL5         |   0 |
+----+-------------+-----+

2 个答案:

答案 0 :(得分:5)

您可以先执行pivot_table,然后执行melt / stack

# all reject codes
Rej_Codes = [f'EL{i+1}' for i in range(5)]

(df.pivot_table(index='ID', 
               columns='Reject Code', 
               values='QTY', 
               fill_value=0)
   .reindex(Rej_Codes, axis=1, fill_value=0) # as pointed out by rafaelc
   .stack()
   .reset_index(name='QTY')
)

输出:

   ID Reject Code  QTY
0   A         EL1    7
1   A         EL2    2
2   A         EL3   33
3   A         EL4    0
4   A         EL5    0
5   B         EL1    7
6   B         EL2    1
7   B         EL3    7
8   B         EL4   36
9   B         EL5    5
10  C         EL1    3
11  C         EL2   32
12  C         EL3    0
13  C         EL4    0
14  C         EL5    0

答案 1 :(得分:3)

让我们使用pd.MultiIndexes和from_products创建丢失的行:

indx = pd.MultiIndex.from_product([df['ID'].unique(), 
                                   df['Reject Code'].unique()], 
                                  names=['ID', 'Reject Code'])

df.set_index(['ID','Reject Code']).reindex(indx, fill_value=0).reset_index()

输出:

      ID    Reject Code  QTY
0    A     EL1             7
1    A     EL2             2
2    A     EL3            33
3    A     EL4             0
4    A     EL5             0
5    B     EL1             7
6    B     EL2             1
7    B     EL3             7
8    B     EL4            36
9    B     EL5             5
10   C     EL1             3
11   C     EL2            32
12   C     EL3             0
13   C     EL4             0
14   C     EL5             0

不是所有的“拒绝代码”都在数据框中,然后您可以使用df ['Reject Codes']。unqiue(),

的列表
indx = pd.MultiIndex.from_product([df['ID'].unique(), ['EL1', 'EL2', 'EL3', 'EL4', 'EL5'], names=['ID', 'Reject Code'])