You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas/Numpy中用自定义函数实现类外积运算?

优化自定义距离矩阵的生成方式

问题描述

我拥有一个包含N行的DataFrame,以及M个质心(每个质心的形状与DataFrame的行完全一致)。需要生成一个N行M列的矩阵,其中第m列由将第m个质心应用到DataFrame后得到。当前通过手动遍历质心+apply的方式实现,希望找到更高效、规范的实现方式。

原实现代码:

df = pd.read_csv('test_data.csv')
centroids = df.sample(n=2)
centroids.reset_index(drop=True, inplace=True)

def getDistanceMatrix(df, centroids):
    distanceMatrix = np.zeros((len(df), len(centroids)))

    distFunc = lambda centroid, row: sum(centroid != row)

    iCentroid = 0
    for _, centroid in centroids.iterrows():
        distanceMatrix[:, iCentroid] = df.apply(
            lambda row: distFunc(centroid, row),
            axis=1
        )
        iCentroid += 1

    return distanceMatrix

distanceMatrix = getDistanceMatrix(df, centroids)

示例test_data.csv数据:

A,B,C,D
1,2,1,1
2,1,1,2
1,2,3,4
2,2,1,2
2,3,3,4
1,1,3,1
4,2,1,2
2,3,3,3
4,1,1,2

更优实现方式

方法1:利用Numpy广播实现向量化计算

你的自定义距离是两个向量对应位置不同元素的个数之和(类似汉明距离),可以直接用Numpy的广播机制完成向量化计算,避免循环和apply这类低效操作:

import pandas as pd
import numpy as np

df = pd.read_csv('test_data.csv')
centroids = df.sample(n=2).reset_index(drop=True)

def getDistanceMatrix(df, centroids):
    # 将DataFrame和质心转为Numpy数组
    df_arr = df.to_numpy()
    centroids_arr = centroids.to_numpy()
    # 广播后计算差异元素的总和:df_arr形状(N,D),centroids_arr形状(M,D)
    # 广播为(N,M,D)的布尔数组,沿最后一维求和得到(N,M)的距离矩阵
    return (df_arr[:, None] != centroids_arr).sum(axis=2)

distanceMatrix = getDistanceMatrix(df, centroids)

优势:

  • 完全向量化操作,效率比原方法提升几个数量级(尤其是数据量较大时)
  • 代码简洁,无需手动初始化矩阵和循环填充

方法2:适配复杂自定义距离的通用方案

如果你的自定义距离函数无法直接用向量化实现,可以用numpy.vectorize封装(注意:vectorize本质是循环的封装,效率不如纯向量化,但比pandas.apply更高效):

def getDistanceMatrix(df, centroids):
    df_arr = df.to_numpy()
    centroids_arr = centroids.to_numpy()
    
    # 定义自定义距离函数
    def dist_func(row, centroid):
        return sum(row != centroid)
    
    # 封装为可广播的vectorized函数
    vec_dist = np.vectorize(dist_func, signature='(d),(d)->()')
    return vec_dist(df_arr[:, None], centroids_arr)

原方法的问题

原方案中iterrows循环和df.apply都是逐行操作,属于Python级别的循环,在数据量较大时会非常缓慢。而Numpy的向量化操作是基于C语言实现的底层运算,能大幅提升执行效率。

内容的提问来源于stack exchange,提问作者P i

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:30:51