高性能适用于按熊猫分组

时间:2020-02-09 07:51:06

标签: python pandas performance apply

我需要在熊猫数据框的列上计算百分位数。数据框的子集如下:

df

我想计算SaleQTY的第20个百分位数,但对于每组[“ Barcode”,“ ShopCode”]: 所以我定义一个函数如下:

def quant(group):
    group["Quantile"] = np.quantile(group["SaleQTY"], 0.2)
    return group

将此功能应用于我的销售数据中的每个组,该销售数据具有将近1800万行和大约300万组[“ Barcode”,“ ShopCode”]:

quant_sale = sales.groupby(['Barcode','ShopCode']).apply(quant)

在具有128 GB Ram和32 Core的Windows服务器上完成此过程需要2个小时。 这没有意义,因为那只是我的代码的一小部分。我开始搜索网络以提高性能。 我想出了以下代码无效的“ numba”解决方案:

from numba import njit, jit
@jit(nopython=True)
def quant_numba(df):
    final_quant = []
    for bar_shop,group in df.groupby(['Barcode','ShopCode']):
        group["Quantile"] = np.quantile(group["SaleQTY"], 0.2)
        final_quant.append((bar_shop,group["Quantile"]))
    return final_quant    
result = quant_numba(sales)  

似乎我不能在此装饰器中使用pandas对象。 enter image description here

我不确定我是否可以使用多重处理(我不熟悉整个概念),或者是否有任何解决方案可以加快我的代码的速度。因此,我们将不胜感激。

2 个答案:

答案 0 :(得分:3)

您可以尝试DataFrameGroupBy.quantile

(function finalization() {
  // get all data in form and return object
  function getFormData(form) {
    var elements = form.elements;
    var honeypot;

    var fields = Object.keys(elements).filter(function(k) {
      if (elements[k].name === 'honeypot') {
        honeypot = elements[k].value;
        return false;
      }
      return true;
    }).map(function(k) {
      if (elements[k].name !== undefined) {
        return elements[k].name;
        // special case for Edge's html collection
      } else if (elements[k].length > 0) {
        return elements[k].item(0).name;
      }
    }).filter(function(item, pos, self) {
      return self.indexOf(item) == pos && item;
    });

    var formData = <any> {};
    fields.forEach(function(name) {
      var element = elements[name];

      // singular form elements just have one value
      formData[name] = element.value;

      // when our element has multiple items, get their values
      if (element.length) {
        var data = [];
        for (var i = 0; i < element.length; i++) {
          var item = element.item(i);
          if (item.checked || item.selected) {
            data.push(item.value);
          }
        }
        formData[name] = data.join(', ');
      }
    });

    // add form-specific values into the data
    formData.formDataNameOrder = JSON.stringify(fields);
    formData.formGoogleSheetName = form.dataset.sheet || 'responses'; // default sheet name
    formData.formGoogleSend
      = form.dataset.email || ''; // no email by default

    return {data: formData, honeypot: honeypot};
  }

或者像用@ {Jon Clements命名的那样,用百分位填充新列一样,使用GroupBy.transform

df1 = df.groupby(['Barcode', 'Shopcode'])['SaleQTY'].quantile(0.2)

答案 1 :(得分:1)

熊猫中有一个内置函数,称为quantile()。

quantile()将有助于获得df中列的第n个百分点。

文档参考link

geeksforgeeks示例reference