多次针对特定ID复制多行事件

时间:2019-09-24 18:20:30

标签: python pandas dataframe vectorization data-manipulation

我有关于客户的通话记录数据。如下所示,其中ID是客户ID,A和B是日志属性:

import pandas as pd 
import numpy as np
df = pd.DataFrame(np.random.randint(0,100,size=(10, 2)), columns=list('AB'),
                  index = ['A','A','A','B','B','C','C','C','D','D'])
df['ID']=df.index
df = df[['ID','A','B']]
  ID   A   B
A  A  46  31
A  A  99  54
A  A  34   9
B  B  46  48
B  B   7  75
C  C   1  25
C  C  71  40
C  C  74  53
D  D  57  17
D  D  19  78

我想基于一些插槽为每个ID复制每个事件集。例如如果广告位值为2,则ID为“ A”的所有事件都应复制广告位1次。

  ID   A   B
A  A  46  31
A  A  99  54
A  A  34   9

A  A  46  31
A  A  99  54
A  A  34   9

,并且应该创建一个新索引来指示复制值属于哪个插槽:

ID   A   B Index
 A  46  31  A-1
 A  99  54  A-1
 A  34   9  A-1

 A  46  31  A-2
 A  99  54  A-2
 A  34   9  A-2

我尝试了以下解决方案:

slots = 2
nba_data = pd.DataFrame()
idx = pd.Index(list(range(1,slots+1))) 

for i in unique_rec_counts_dict:
    b = df.loc[df.ID==i,:]
    b = b.append([b]*(slots-1),ignore_index=True)
    b['Index'] = str(i)+'-'+idx.repeat(unique_rec_counts_dict[i]).astype(str)
    nba_data = nba_data.append(b)

它给了我预期的输出,但是当插槽增加并且客户数量增加10k时,它不能扩展。

  ID   A   B Index
0  A  46  31   A-1
1  A  99  54   A-1
2  A  34   9   A-1
3  A  46  31   A-2
4  A  99  54   A-2
5  A  34   9   A-2
0  B  46  48   B-1
1  B   7  75   B-1
2  B  46  48   B-2
3  B   7  75   B-2
0  C   1  25   C-1
1  C  71  40   C-1
2  C  74  53   C-1
3  C   1  25   C-2
4  C  71  40   C-2
5  C  74  53   C-2
0  D  57  17   D-1
1  D  19  78   D-1
2  D  57  17   D-2
3  D  19  78   D-2

由于循环,我认为它花费了很长时间。向量化的任何解决方案都将非常有用。

1 个答案:

答案 0 :(得分:1)

您可以尝试:

slots = 2
new_df = pd.concat(df.assign(Index=f'_{i}') for i in range(1, slots+1))

new_df['Index'] = new_df['ID'] + new_df['Index']

输出:

  ID   A   B Index
A  A  48  61   A_1
A  A  70  13   A_1
A  A  36  23   A_1
B  B  22  66   B_1
B  B  92  95   B_1
C  C  53   9   C_1
C  C  41  57   C_1
C  C  88  93   C_1
D  D  76  82   D_1
D  D  11  36   D_1
A  A  48  61   A_2
A  A  70  13   A_2
A  A  36  23   A_2
B  B  22  66   B_2
B  B  92  95   B_2
C  C  53   9   C_2
C  C  41  57   C_2
C  C  88  93   C_2
D  D  76  82   D_2
D  D  11  36   D_2