如何对在两个熊猫数据帧上运行的函数进行矢量化处理?

时间:2020-09-24 18:05:13

标签: python pandas

我有两个熊猫数据框;这是它们的外观的一些较小示例:

utils = pd.DataFrame({'A1L1': [-0.42, 0.13, 1.56],
                      'A1L2': [-0.21, -0.01, 0.74],
                      'A1L3': [0.63, -0.12, -2.30],
                      'A2L1': [-0.63, 0.42, 0.33],
                      'A2L2': [0.63, -0.42, -0.33],
                      'A3L1': [-0.10, -0.34, 0.23],
                      'A3L2': [0.10, 0.34, -0.23],
                      'weight': [1.1, 0.9, 1.0],
                      'others': [4.23, 5.21, 4.88]})

settings = pd.DataFrame({0: [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
                         1: [1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2],
                         2: [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]})

在我的实际情况中,utils数据帧具有更多的A_L_变量集和1,000行。 settings数据帧具有更多列(utils数据帧中的每一列A列)和460,000行。

我想对settings数据帧的每一行执行一个依赖于utils数据帧的功能。

首先,我想从utils中提取与settings中的每一列相对应的L列;我的意思是,如果列0的值为1,则应拉A1L1列。如果列0的值为3,则应拉A1L3列。如果第2列的值为1,则应拉A3L1列。

然后,我想对每一行的那些列求和,对求和求幂,将求和后的求和除以“ +”其他列,再乘以“ weight”列,求和,最后除以“重量”列的总和。这是我为settings数据帧的一行编写的函数:

def pref_share(row, df, weight, others):
    # Get names of attribute/level pairs
    var_names = "A" + (pd.Series(row).index+1).astype(str) + "L" + pd.Series(row).astype(str)

    # Compute share
    share = ((np.exp(df[var_names].sum(axis=1))/ \
              (np.exp(df[var_names].sum(axis=1)) + df[others].values)) \
             *df[weight]).sum(axis=0) / df[weight].sum(axis=0)
    return share

要对此settings中的每一行进行计算,我将.apply()与lambda一起使用以将其应用于设置数据框:

settings["share"] = settings.apply(lambda row: pref_share(row, utils, "weight", "others"), axis=1)

将所有数学运算放在一行中确实可以提高速度,将速度减少到原来的一半,但是仍然需要大约45分钟才能运行。我在想,如果我可以找到一种矢量化方法,而不必使用.apply(),那可能会有所帮助。我还遇到了一些有关numba模块的答案,但似乎它不接受pandas数据框,因此我认为这可能是一种选择。

0 个答案:

没有答案