python 3. +,根据pivot_table的平均价格创建一个新的分类列

时间:2017-02-03 05:47:23

标签: python python-3.x pandas

在我的表格中,我有两列: Item_Identifier 销售(实际上,表格中有20列,但其他列不需要在这种情况下被考虑)。我想在表格中创建一个列,将销售价格分为三类:低,中和高。

初始表如下所示:

dir /b /s > fileslist.csv

我想要的决赛桌:

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

因为相同的Item_Identifier可以有不同的促销价格,所以我使用pivot_table来获取每件商品的平均价格。我想通过item_sale_avg确定三个类别(低,中和高)。

我的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_sale_avg=combine.pivot_table(values='Sales',index='Item_Identifier')

我意识到即使上面的代码工作,它运行得很慢。请随时给我一个主意。非常感谢。

2 个答案:

答案 0 :(得分: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

使用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

编辑:

您需要先dict pivot_table创建groupbymean groupby {更快pivot_table 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 ):

{{1}}

答案 1 :(得分: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 应该处理对齐索引):

#import <NMAKit/NMAKit.h>