如何使用Pandas进一步优化代码以解决所需问题

2024-06-02 06:53:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了以下数据集

dataset1 = { 'srid':[1,2,3,1,5],
            'custid':[11,12,43,12,34],
            'orderdate':["1/2/2019","1/2/2019","2/2/2019","1/2/2019","1/2/2019"],
            'Rev':[100,101,102,103,17]
}

df1 = pd.DataFrame(dataset1)

我必须将每个销售代表标记为: 优秀(他一天的总收入是平均收入的1.5倍或更高) 当天的所有销售代表) 良好(其一天的总收入小于1.5倍且大于等于1.1倍 乘以当天所有销售代表的平均收入) 平均(其一天的总收入小于1.1倍且大于等于 至当天所有销售代表平均收入的0.9倍) 穷人(他一天的总收入不到所有人平均收入的0.9倍) “数据集1”中存在的每个日期的销售代表 输出数据集:销售代表ID、订单日期、标记

我尝试的是:

g=df.groupby(df['orderdate'])
ans={}
for od,od_df in g:
   # print(od)
    ans[od]=list()
    x=od_df["Rev"].mean()
    s=set(od_df["srid"].tolist())
    for i in s:
        p=od_df[od_df["srid"]==i]["Rev"].sum()
        val = p/x
        if val>=1.5:
            ans[od].append([i,od,"Excellent"])
        elif 1.1<=val<1.5:
            ans[od].append([i,od,"good"])
        elif 0.9<=val<1.1:
            ans[od].append([i,od,"avg"])
        else:
            ans[od].append([i,od,"poor"])

但这很难写,而且在大数据集上需要更多的时间。我如何进一步优化它


Tags: 数据标记dfforrev代表valsrid
3条回答

我会做那样的事

list_df = []
for date in df.orderdate.unique():
    df_cur = df[df.orderdate==date]
    mean = df_cur.rev.Mean()
    def get_rank(rev):
        if rev > 1.5*mean:
           return "Good"
        elif rev .......
    df_cur["Ranking"]=df_cur.rev.apply(get_rank)
    list_df.append(df_cur)
df_final = pd.concat(list_df)

我的意思是,你需要调整它,但我认为它应该有效

对于每个日期,我得到以下数据帧,然后得到当天的排名。最后,我合并所有的数据帧以获得所有的日期

只需添加一个要计算的列并对结果进行“应用”

df1['mean'] = df1.loc[:,['orderdate','Rev']].groupby('orderdate').transform('mean')
df1['Representative'] = df1['Rev']/df1['mean']

def rep(x):
    if x >= 1.5:
        return 'Excellent'
    elif 1.1<=x<1.5:
        return 'good'
    elif 0.9<=x<1.1:
        return 'avg'
    else:
        return 'poor'

df1['Marking'] = df1['Representative'].apply(rep)
df1
    srid    custid  orderdate   Rev mean    Representative  Marking
0   1   11  1/2/2019    100 80.25   1.246106    good
1   2   12  1/2/2019    101 80.25   1.258567    good
2   3   43  2/2/2019    102 102.00  1.000000    avg
3   1   12  1/2/2019    103 80.25   1.283489    good
4   5   34  1/2/2019    17  80.25   0.211838    poor

与您的相比,我无法真正测试实现的速度,因为对于5个值,它比其他任何东西都更能衡量开销。然而,在熊猫身上,裸环往往效率很低。你可以得到平均值的相对差值,如下所示:

In [15]: df.groupby('orderdate').apply(lambda _df: _df['Rev'] / _df['Rev'].mean())                                                                                                                         
Out[15]: 
orderdate   
1/2/2019   0    1.2461
           1    1.2586
           3    1.2835
           4    0.2118
2/2/2019   2    1.0000
Name: Rev, dtype: float64

并使用pd.cut将其转换为有序刻度

In [28]: df['RevMark'] = pd.cut(df.groupby('orderdate').apply(lambda _df: _df['Rev'] / _df['Rev'].mean()).sort_index(level=1).values, [0,0.9,1.1,1.5,np.inf], labels=['poor', 'avg', 'good', 'excellent']) 

In [29]: df                                                                                                                                                                                                
Out[29]: 
   srid  custid orderdate  Rev RevMark
0     1      11  1/2/2019  100    good
1     2      12  1/2/2019  101    good
2     3      43  2/2/2019  102     avg
3     1      12  1/2/2019  103    good
4     5      34  1/2/2019   17    poor

sort_index是必需的,因为在分组之后,值是按日期排序的,因此关联是错误的。cut的第二个参数是所需间隔的边界,标签是您所调用的标记

就时间而言,你需要自己在足够大的样本上进行测量

相关问题 更多 >