2017-01-27 7 views
3

を分割列のすべての可能な順列を作成します。私はこのようになりますデータフレーム持っているパンダDATAFRAMEに別の列で

Final State

:私の目的はで取得することです

Current State

説明:

  1. すべての顧客は、
  2. 各注文で多くのカテゴリから1つ購入できます
  3. 希望の状態:顧客が注文シーケンスで購入したすべての可能な並べ替えを取得します。 2番目の画像はこれをよりよく理解するのに役立ちます。
  4. 希望の状態のカテゴリ1は一番最初に購入したカテゴリを表し、カテゴリ2は二次で購入したカテゴリを表します。私が使用している

コード:

start_time = time.time() 

df = pd.DataFrame() 
for CustomerName in base_df.CustomerName.unique(): 
    df1 = base_df[(base_df['CustomerName']== CustomerName)][['CustomerName','order_seq','Category']] 
    df2 = pd.DataFrame(index=pd.MultiIndex.from_product([subdf['Category'] for p, subdf in df1.groupby(['order_seq'])], names = df1.order_seq.unique())).reset_index() 
    df2['CustomerName'] = CustomerName 
    df = df.append(df2) 

print("--- %s seconds ---" %(time.time() - start_time)) 

これは私のデータセット上で実行するのに約10分かかります - より高速な方法を探しています。

私は現在Pandasに取り組んでいますが、RまたはSQLのポインタも歓迎します!ありがとうございます!

+0

これは順列ですか?なぜ顧客1は最初の注文でしか食べ物を注文できないのですか? –

+0

ようこそスタックオーバーフロー!最初に[ツアー(http://stackoverflow.com/tour)に参加して[良い質問をする方法](http://stackoverflow.com/help/how-to-ask)を学んで[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例を参照してください。そうすれば、私たちがあなたを助けやすくなります。 –

+0

@PauloMiraMor - いいえ、何でもかまいません。彼は衣服、家具、またはその両方を最初の注文で購入することができました。はい、各顧客の注文シーケンスによるすべての製品の順列が必要です – Tanya

答えて

0

大丈夫です。いくつかの仕事を取ったが、私はそれをやった。それが役に立てば幸い。

import pandas as pd 
import numpy as np 
from itertools import combinations 

df = pd.DataFrame([], columns=['CustomerName','Order Sequence','Category']) 

df['CustomerName'] = [1,1,1,1,1,1,1,2,2,2,3,3,3,3] 
df['Order Sequence'] = [1,2,2,2,3,3,3,1,2,3,1,1,2,3] 
df['Category'] = ['Food','Food','Clothes','Furniture','Clothes','Food','Toys','Clothes','Toys','Food','Furniture','Toys','Food','Food'] 

df2 = pd.DataFrame([], columns=['CustomerName','Category1','Category2','Category3']) 

for CN in sorted(set(df['CustomerName'])): 

    df_temp = pd.DataFrame([], columns=['CustomerName','Category1','Category2','Category3']) 

    list_OS_1 = [] 
    list_OS_2 = [] 
    list_OS_3 = [] 

    MMC = reduce(lambda x, y: x*y,df.loc[df['CustomerName']==CN, 'Order Sequence'].value_counts().values) 

    for N in np.arange(MMC/len(df.loc[((df['CustomerName']==CN) & (df['Order Sequence']==1)), 'Category'])): 

     for CTG in df.loc[((df['CustomerName']==CN) & (df['Order Sequence']==1)), 'Category']: 

      list_OS_1.append(CTG) 

    for N in np.arange(MMC/len(df.loc[((df['CustomerName']==CN) & (df['Order Sequence']==2)), 'Category'])): 

     for CTG in df.loc[((df['CustomerName']==CN) & (df['Order Sequence']==2)), 'Category']: 

      list_OS_2.append(CTG) 

    for N in np.arange(MMC/len(df.loc[((df['CustomerName']==CN) & (df['Order Sequence']==3)), 'Category'])): 

     for CTG in df.loc[((df['CustomerName']==CN) & (df['Order Sequence']==3)), 'Category']: 

      list_OS_3.append(CTG) 

    df_temp['Category1'] = list_OS_1 
    df_temp['Category2'] = list_OS_2 
    df_temp['Category3'] = list_OS_3 
    df_temp['CustomerName'] = CN 

    df2 = pd.concat([df2,df_temp],0) 

print (df2) 

出力:

CustomerName Category1 Category2 Category3 
0   1.0  Food  Food Clothes 
1   1.0  Food Clothes  Food 
2   1.0  Food Furniture  Toys 
3   1.0  Food  Food Clothes 
4   1.0  Food Clothes  Food 
5   1.0  Food Furniture  Toys 
6   1.0  Food  Food Clothes 
7   1.0  Food Clothes  Food 
8   1.0  Food Furniture  Toys 
0   2.0 Clothes  Toys  Food 
0   3.0 Furniture  Food  Food 
1   3.0  Toys  Food  Food 

がPS:その動のない、あなたはそれを超えるfckedちゃうカテゴリを追加または削除ので、もし。 しかし限り、それはあなたが私を渡された最初の標準を次のように、それはSHLD仕事

+0

ありがとうございます!私は残念ながら新しいカテゴリを追加したかもしれません! – Tanya

1

それぞれが別個CustomerNameのに参加し、3つのOrderSequenceデータフレームのマージを考えてみましょう:

import pandas as pd 

df = pd.DataFrame({'CustomerName': [1,1,1,1,1,1,1,2,2,2,3,3,3,3], 
        'OrderSequence': [1,2,2,2,3,3,3,1,2,3,1,1,2,3], 
        'Category': ['Food','Food','Clothes','Furniture','Clothes','Food','Toys', 
           'Clothes','Toys','Food','Furniture','Toys','Food','Food']}) 

finaldf = pd.DataFrame(df['CustomerName'].drop_duplicates()) 

for i in range(1,4): 
    seqdf = df[df['OrderSequence']==i][['CustomerName', 'Category']].\    
             rename(columns={'Category':'Category'+str(i)}) 
    finaldf = pd.merge(finaldf, seqdf, on=['CustomerName']) 

print(finaldf) 

#  CustomerName Category1 Category2 Category3 
# 0    1  Food  Food Clothes 
# 1    1  Food  Food  Food 
# 2    1  Food  Food  Toys 
# 3    1  Food Clothes Clothes 
# 4    1  Food Clothes  Food 
# 5    1  Food Clothes  Toys 
# 6    1  Food Furniture Clothes 
# 7    1  Food Furniture  Food 
# 8    1  Food Furniture  Toys 
# 9    2 Clothes  Toys  Food 
# 10    3 Furniture  Food  Food 
# 11    3  Toys  Food  Food 

確かに、上記のセットアップは、自己結合を使用してSQLで最初に考案され、次にパンダに翻訳されました:

SELECT t1.CustomerName, t2.Category AS Category1, 
     t3.Category AS Category2, t4.Category AS Category3 

FROM (SELECT DISTINCT CustomerName FROM DataFrame) AS t1 
INNER JOIN DataFrame AS t2 
ON t1.CustomerName = t2.CustomerName 
INNER JOIN DataFrame AS t3 
ON t1.CustomerName = t3.CustomerName 
INNER JOIN DataFrame AS t4 
ON t1.CustomerName = t4.CustomerName 

WHERE (t2.OrderSequence=1) AND (t3.OrderSequence=2) AND (t4.OrderSequence=3); 
+0

ありがとう、あなたのロジックを実行し、私のデータ上でより速く動作するかどうか試してみましょう! – Tanya

+0

そして、私たちは実際のデータで何を見つけましたか? – Parfait

関連する問題