2017-02-03 4 views
1

から平均価格に基づいて新しいカテゴリの列を作成し、私は2つの列があります。Item_Identifier販売(実際には、そこに20個の列がテーブルにあるが、他の列この場合は考慮する必要はありません)。販売価格を低、中、高の3つのカテゴリに分ける列をテーブルに作成します。同じItem_Identifier私は平均を得るためにpivot_table使用し、異なる販売価格を持つことができるためのpython 3. +、私のテーブルでpivot_table

Item_Identifier Sales  Categories 
    Milk    500   medium 
    Milk    1200  medium 
    Milk    2000  medium 
    Beef    60   high 
    Beef    6000  high 
    Tea    150   low   
    Tea    100   low 
    Tea    200   low 
    .     . 
    .     . 
    .     . 

:私が欲しい

Item_Identifier Sales 
    Milk    500 
    Milk    1200 
    Milk    2000 
    Beef    60 
    Beef    6000 
    Tea    150 
    Tea    100 
    Tea    200 
    .     . 
    .     . 
    .     . 

ファイナルテーブル:

初期テーブルは次のようになります各商品の価格。そして、私はitem_sale_avgによって3つのカテゴリ(低、中、高)を特定したいと思います。

マイpivot_tableコードはこれを好き:

item_sale_avg=combine.pivot_table(values='Sales',index='Item_Identifier') 

私はこの問題を解決するために以下のコードを使用しようとするが、それは本当に私が望む結果得られません。

def price_category(data,id_col,new_col,price_pivot_table): 
    data[new_col]='' 
    i=-1 
    for item in data[id_col]: 
     i+=1 
     if price_pivot_table[item]>500: 
      data.loc[i,new_col]='low' 
     elif price_pivot_table[item]>=500 or price_pivot_table[item]<1500: 
      data.loc[i,new_col]='medium' 
     else: 
      data.loc[i,new_col]='high' 

をそして、私はことを実現上記のコードでさえ、かなり遅く動作します。私にアイデアを教えてください。どうもありがとう。

答えて

2

あなたはcutを使用することができます。

item_sale_avg = pd.DataFrame({'Sales':[100,500,600,1500,2000]}) 

print (item_sale_avg) 
    Sales 
0 100 
1 500 
2 600 
3 1500 
4 2000 

bins = [-np.inf,500, 1500, np.inf] 
labels=['low','medium','high'] 
item_sale_avg['Price Category'] = pd.cut(item_sale_avg['Sales'], bins=bins, labels=labels) 
print (item_sale_avg) 
    Sales Price Category 
0 100   low 
1 500   low 
2 600   medium 
3 1500   medium 
4 2000   high 

#bins not include the rightmost edge - parameter right=False 
item_sale_avg['Price Category'] = pd.cut(item_sale_avg['Sales'], 
             bins=bins, labels=labels, right=False) 
print (item_sale_avg) 
    Sales Price Category 
0 100   low 
1 500   medium 
2 600   medium 
3 1500   high 
4 2000   high 

別の少ない柔軟なソリューションのワットi番目のnumpy.where

item_sale_avg['Price Category'] = np.where(item_sale_avg.Sales <= 500, 'low', 
            np.where(item_sale_avg.Sales >= 1500, 'high', 'medium')) 

print (item_sale_avg) 
    Sales Price Category 
0 100   low 
1 500   low 
2 600   medium 
3 1500   high 
4 2000   high 

item_sale_avg['Price Category'] = np.where(item_sale_avg.Sales < 500, 'low', 
            np.where(item_sale_avg.Sales >= 1500, 'high', 'medium')) 

print (item_sale_avg) 
0 100   low 
1 500   medium 
2 600   medium 
3 1500   high 
4 2000   high 

タイミング

item_sale_avg = pd.DataFrame({'Sales':[100,500,600,1500,2000]}) 

print (item_sale_avg) 
item_sale_avg = pd.concat([item_sale_avg]*100000).reset_index(drop=True) 

In [19]: %timeit item_sale_avg['Price Category'] = np.where(item_sale_avg.Sales < 500, 'low', np.where(item_sale_avg.Sales >= 1500, 'high', 'medium')) 
10 loops, best of 3: 70.4 ms per loop 

#ResMar solution 
In [20]: %timeit item_sale_avg['Price Category1'] = item_sale_avg['Sales'].map(lambda price: 'low' if price < 500 else 'medium' if price < 1500 else 'high') 
10 loops, best of 3: 125 ms per loop 

In [21]: %timeit item_sale_avg['Price Category2'] = pd.cut(item_sale_avg['Sales'], bins=[-np.inf,500, 1500, np.inf], labels=['low','medium','high'], right=False) 
100 loops, best of 3: 9.17 ms per loop 

はEDIT:

あなたはpivot_tableまたはgroupbyのWiから作成dictによる最初のmapが必要mean番目(速いpivot_tableとしてgroupbyです):あなたのソリューションのための

d = df.groupby('Item_Identifier')['Sales'].mean().to_dict() 
print (d) 
{'Beef': 3030.0, 'Milk': 1233.3333333333333, 'Tea': 150.0} 

print (df['Item_Identifier'].map(d)) 
0 1233.333333 
1 1233.333333 
2 1233.333333 
3 3030.000000 
4 3030.000000 
5  150.000000 
6  150.000000 
7  150.000000 
Name: Item_Identifier, dtype: float64 

bins = [df['Sales'].min(),500, 1500, df['Sales].max()] 
labels=['low','medium','high'] 
df['Price Category'] = pd.cut(df['Item_Identifier'].map(d), bins=bins, labels=labels) 
print (df) 
    Item_Identifier Sales Price Category 
0   Milk 500   medium 
1   Milk 1200   medium 
2   Milk 2000   medium 
3   Beef  60   high 
4   Beef 6000   high 
5    Tea 150   low 
6    Tea 100   low 
7    Tea 200   low 
+0

感謝。しかし、私はpivot_tableからの平均価格を見て、新しい列を作成したいと思います。 item_sale_avgはpivot_tableの名前です。 –

+0

変更された解決策を確認してください。 – jezrael

+0

おっと、申し訳ありません。修正していただきありがとうございます。 – jezrael

0

このコードは、シリアル番号locの操作を実行し、DataFrameを反復処理しているため、実行速度が遅くなります。途中で多数のコピーが作成されるため、お勧めできません。

高速コードパスはmapです。あなたは上price_categoryを実行しているものを示さなかったので、私は何をやっている伝えることはできませんが、私はあなたがこのような何かしたいと思う:あなたの元のデータセットに結果を割り当てるためにその後

price_categories = item_sale_avg['Sales'].map(
    lambda price: 'low' if price < 500 else 'medium' if price < 1500 else 'high' 
) 

を(pandasはあなたのためのインデックスを揃える処理する必要があります):

data['Price Category'] = price_categories 
関連する問題