Skip to main content
 首页 » 编程设计

python之如何矢量化 Pandas 操作以提高速度

2025年05月04日19leader

这是一个SKU亲和性问题。我有一个这样的数据框。每个 ctn_id 都有多个 sku_code。

dfr = pd.DataFrame(columns=['ctn_id','sku_code']) 
dfr['ctn_id'] = np.random.randint(low=1,high=21,size=200) 
dfr['sku_code'] = np.random.choice(['a','b','c','d'],size=200) 
dfr.drop_duplicates(['ctn_id','sku_code'], inplace=True) 

我想填写以下数据框。

dfx = pd.DataFrame(columns=['sku_code','a','b','c','d']) 
dfx['sku_code'] = ['a','b','c','d'] 
dfx = dfx.fillna(0) 
dfx.set_index('sku_code',inplace=True) 

使用下面的逻辑

for idx in dfr['ctn_id'].unique(): 
    x = list(dfr[dfr['ctn_id'] == idx]['sku_code'].unique()) 
    for skui in dfx.index: 
        if skui in x: 
            for skuj in x: 
                dfx.loc[skui, skuj] = dfx.loc[skui, skuj] + 1 

我有 250 万个 ctn_ids 和 400 个 sk_codes,总共有十亿次赋值操作。使用 pandas 或任何其他包是否有更好的方法来做到这一点?

请您参考如下方法:

对于具有整数的ctn_id,我们可以使用基于数组赋值的方法来获取2D <上的所有映射< code> 网格,然后使用矩阵乘法得到 binned-summations,类似于 @scomes's post 中所示-

Ie = dfr.ctn_id.values 
J = dfr.sku_code.values 
 
I = pd.factorize(Ie,sort=False)[0] 
col2IDs,col2L = pd.factorize(J,sort=True) #use sort=False if order is irrelevant 
a = np.zeros((I.max()+1,col2IDs.max()+1),dtype=int) 
a[I,col2IDs] = 1 
df_out = pd.DataFrame(a.T.dot(a), columns=col2L, index=col2L) 

备选 #1

为了获得更好的性能,我们可以使用 float 值进行矩阵乘法。为此,使用 float dtype 来获取 a。因此,像这样设置 a -

a = np.zeros((I.max()+1,col2IDs.max()+1),dtype=float) 

备选 #2

或者使用 bool 数组存储1,然后转换dtype:

a = np.zeros((I.max()+1,col2IDs.max()+1),dtype=bool) 
a[I,col2IDs] = 1 
a = a.astype(float)