2017-08-09 124 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'])