我有一个自行车的数据集,其中有商店的列,销售的列以及有关自行车型号的一些信息。 我需要比较每个商店中模型的销售数量。因此,我需要执行以下操作:
按商店分组自行车:
groups = df.groupby('store_id')
然后,对于该商店中的每个模型,我需要找到具有相似特征的模型。那是相似的高度,长度,重量等。为此,我设置了10%的差异界限,这意味着如果两个模型之间的重量差异小于10%,则另一个模型是可比较的邻居。
最后,对于每种型号,我想看看它在竞争对手中的排名,如果它的表现优于竞争对手,则给它一个“最畅销”的标签。
问题是,我不知道如何执行第2步和第3步。有人有主意吗?我看过pandas文档中的Groupby.Transform,但是我不知道它如何适合整个图片。
您的帮助将不胜感激!
答案 0 :(得分:1)
尝试一下:
import pandas as pd
import numpy as np
def sales_rank(x, df):
df_ns = df.set_index('id')
df_ns = df_ns.loc[x.neighbors, 'sales']
df_ns.sort_values(ascending=False, inplace=True)
df_ns = df_ns.reset_index()
return df_ns[df_ns.id == x.id].index[0]
df = pd.DataFrame(data={'id': range(5), 'weight': [20, 21, 23, 43, 22], 'sales':[200, 100, 140, 100, 100]})
df['neighbors'] = df.weight.apply(lambda x: df.id[np.isclose(df.weight.values, x, rtol=0.10)].values)
df['sales_rank_in_neighborhood'] = df.apply(lambda x: sales_rank(x, df) , axis=1)
df['top_seller'] = df.apply(lambda x: x.sales_rank_in_neighborhood < len(x.neighbors)//2, axis=1)
print(df)
id weight sales neighbors sales_rank_in_neighborhood top_seller
0 0 20 200 [0, 1, 4] 0 True
1 1 21 100 [0, 1, 2, 4] 3 False
2 2 23 140 [1, 2, 4] 0 True
3 3 43 100 [3] 0 False
4 4 22 100 [0, 1, 2, 4] 2 False
请注意,在单元素社区中没有畅销书。调整规则以适合您的目的。
我希望这会有所帮助!
我添加了针对群体的解决方案,用于定义邻域的多个规则以及固定的销售排名实施方式:
import pandas as pd
import numpy as np
def ns(x, df):
weight_rule = np.isclose(df.weight.values, x.weight, rtol=0.10)
gear_rule = df.gear == x.gear
type_rule = df.type == x.type
return df.id[np.logical_and.reduce((weight_rule, gear_rule, type_rule))].values
def sales_rank(x, df):
df_ns = df.set_index('id')
df_ns = df_ns.loc[x.neighbors, 'sales']
df_ns.sort_values(ascending=False, inplace=True)
df_ns = df_ns.reset_index()
return df_ns[df_ns.id == x.id].index[0]
df = pd.DataFrame(data={'store_id': [0, 1, 0, 1, 0], 'id': range(5), 'weight': [20, 21, 23, 43, 22], 'gear': [3, 3, 3, 7, 3], 'type':['mountain', 'mountain', 'mountain', 'bmx', 'mountain'], 'sales':[200, 100, 140, 100, 100]})
# Columns for results
df['neighbors'] = ''
df['sales_rank_in_neighborhood'] = ''
df['top_seller'] = ''
groups = df.groupby('store_id')
for _, g in groups:
df_temp = df.loc[g.index, :]
df_temp.neighbors = df_temp.apply(lambda x: ns(x, df_temp), axis=1)
df_temp.sales_rank_in_neighborhood = df_temp.apply(lambda x: sales_rank(x, df_temp), axis=1)
df_temp.top_seller = df_temp.apply(lambda x: x.sales_rank_in_neighborhood < len(x.neighbors)//2, axis=1)
df.loc[g.index, :] = df_temp
print(df)
store_id id weight gear type sales neighbors sales_rank_in_neighborhood top_seller
0 0 0 20 3 mountain 200 [0, 4] 0 True
1 1 1 21 3 mountain 100 [1] 0 False
2 0 2 23 3 mountain 140 [2, 4] 0 True
3 1 3 43 7 bmx 100 [3] 0 False
4 0 4 22 3 mountain 100 [0, 2, 4] 2 False
我想会有一种避免循环访问组的方法,但这似乎可以解决问题。