请帮助!
共有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 |
+----+-------------+-----+
答案 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'])