我需要在熊猫数据框的列上计算百分位数。数据框的子集如下:
我想计算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)
我不确定我是否可以使用多重处理(我不熟悉整个概念),或者是否有任何解决方案可以加快我的代码的速度。因此,我们将不胜感激。
答案 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)