2017-08-09 201 views
1

即时通讯新的Python和我正在熊猫数据框上工作。Python:从熊猫数据框爆炸行

所以我必须像一个数据帧:

Client_id Nb_Products 
1   2 
2   3 
3   1 

,我需要爆发的每一行Nb_Products次,每次CLIENT_ID。 所以我需要输出如下表:

Client_id Product_Nb 
1   1 
1   2 
2   1 
2   2 
2   3 
3   1 

起初,我想我应该创建一个数字范围为Nb_Products像:

Client_id Nb_Products_rng 
1   [1,2] 
2   [1,2,3] 
3   [1] 

然后爆炸了。 但我无法成功创建这个。

我会很乐意回答任何问题或答案的一部分。 谢谢

+0

开始我个人讨厌把名单在大熊猫'dataframe'这样的事情的想法 - 我看到这一切的时间,这里没有必要 –

回答

0

方法

我用一个指数,首先要加快速度,并获得唯一的客户端ID

df = df.set_index('Client_id') 
client_ids = df.index.get_level_values('Client_id').unique() 

然后我每客户端遍历所有产品的重建数据帧

res = pd.DataFrame(
    [ 
     [client, prod] 
     for client in client_ids 
     for prod in range(1, df.loc[client, 'Nb_Products'].max()+1) 
    ], 
    columns = ['Client_id', 'Nb_Products'] 
) 

示例/测试

测试数据我用

import pandas as pd 
df = pd.DataFrame(
    [[1, 2], [2, 3], [3, 3]], 
    columns=['Client_id', 'Nb_Products'] 
) 

初始数据帧

Client_id Nb_Products 
0   1   2 
1   2   3 
2   3   3 

结果

Client_id Nb_Products 
0   1   1 
1   1   2 
2   2   1 
3   2   2 
4   2   3 
5   3   1 
6   3   2 
7   3   3 
+0

您确定输出与OP的要求相符吗?是不是返回相同的数据帧 –

+0

@ClockSlave这正是我所需要的。感谢您的帮助,我也会尝试您的建议并让您知道。 –

0

您可以简单地通过Client_idNb_products时间重复值 '爆炸' 你的数据集做。通过在Nb_products列中的值对它重复连接Client_id值将产生新数据帧的Client_id变量。我使用列表理解来做到这一点。

要获得第二列 - Product_Nb你只需要简单的顺序从1

from io import StringIO 
import pandas as pd 

TESTDATA=StringIO("""Client_id Nb_Products 
1 2 
2 3 
3 1""") 

df = pd.read_csv(TESTDATA, sep=" ") 

col1 = [] 
_ = [col1.extend([a]*b) for a,b in zip(df.iloc[:,0].values.tolist(), df.iloc[:,1].values.tolist())] 
col2 = [] 
_ = [col2.extend(list(range(1,i+1))) for i in df.iloc[:,1].values.tolist()] 

df2 = pd.DataFrame(list(zip(col1,col2)),columns = ['Client_id', 'Product_Nb'])