动态创建自定义聚合以与 Pandas groupby 一起使用
Creating custom aggregations dynamically to use with Pandas groupby
我正在尝试动态创建一个 lambda 函数字典以传递到 Pandas 中的 agg() 函数并计算“异常”的数量。
def prepareAggDict(defDict):
aggdict={}
# iterate over features with upper limit threshold
for feature_a, threshold_a in defDict.items():
aggdict[feature_a] = lambda x: (x >= threshold_a).sum()
return(aggdict)
并且我希望传递具有不同阈值的不同字段名称,以按以下方式聚合:
aggdict = prepareAggDict({"column_a":3500, "column_b":8200})
dailyAgg = df.groupby([id_col,Date_col]).agg(aggdict)
但由于某种原因,聚合仅应用 column_b 的第二项,而不应用 column_a 的第一项。
我试图在 prepareAggDict 函数中将它们分成不同的 lambda,它确实运行良好。不幸的是,我必须为不同的列创建大约 7 个不同的阈值,我想通过将多个列名称及其阈值传递到一个方法中来创建它,该方法将生成自定义聚合函数的字典以传递给带有 agg( )
例如:
data = {
"id_col":["A","A","B","B","B"],
"column_a":[500,4500,8100,300,11500],
"column_b":[800,22340,7554,300,900]
}
df = pd.DataFrame(data)
aggdict = prepareAggDict({"column_a":3500, "column_b":8200})
dailyAgg = df.groupby(["id_col"]).agg(aggdict)
将产生:
我希望 A 组中的 column_a 的值为 1,B 组的值为 2。
dict
在dict.get
中使用 lambda 函数进行匹配,如果没有匹配返回缺失值:
aggdict = {"column_a":3500, "column_b":8200}
dailyAgg = df.groupby(["id_col"]).agg(lambda x: (x >= aggdict.get(x.name, np.nan)).sum())
print (dailyAgg)
column_a column_b
id_col
A 1 1
B 2 0
编辑:我认为在你的解决方案中没有通过 x
组值,这里是 :
的可能解决方案
def prepareAggDict(p):
def ipf(x):
return (x >= p).sum()
return ipf
data = {
"id_col":["A","A","B","B","B"],
"column_a":[500,4500,8100,300,11500],
"column_b":[800,22340,7554,300,900]
}
df = pd.DataFrame(data)
d = {"column_a":3500, "column_b":8200}
aggdict = {k: prepareAggDict(v) for k, v in d.items()}
#return same like
#aggdict = {"column_a":prepareAggDict(3500), "column_b":prepareAggDict(8200)}
dailyAgg = df.groupby(["id_col"]).agg(aggdict)
print (dailyAgg)
column_a column_b
id_col
A 1 1
B 2 0
我正在尝试动态创建一个 lambda 函数字典以传递到 Pandas 中的 agg() 函数并计算“异常”的数量。
def prepareAggDict(defDict):
aggdict={}
# iterate over features with upper limit threshold
for feature_a, threshold_a in defDict.items():
aggdict[feature_a] = lambda x: (x >= threshold_a).sum()
return(aggdict)
并且我希望传递具有不同阈值的不同字段名称,以按以下方式聚合:
aggdict = prepareAggDict({"column_a":3500, "column_b":8200})
dailyAgg = df.groupby([id_col,Date_col]).agg(aggdict)
但由于某种原因,聚合仅应用 column_b 的第二项,而不应用 column_a 的第一项。 我试图在 prepareAggDict 函数中将它们分成不同的 lambda,它确实运行良好。不幸的是,我必须为不同的列创建大约 7 个不同的阈值,我想通过将多个列名称及其阈值传递到一个方法中来创建它,该方法将生成自定义聚合函数的字典以传递给带有 agg( )
例如:
data = {
"id_col":["A","A","B","B","B"],
"column_a":[500,4500,8100,300,11500],
"column_b":[800,22340,7554,300,900]
}
df = pd.DataFrame(data)
aggdict = prepareAggDict({"column_a":3500, "column_b":8200})
dailyAgg = df.groupby(["id_col"]).agg(aggdict)
将产生:
我希望 A 组中的 column_a 的值为 1,B 组的值为 2。
dict
在dict.get
中使用 lambda 函数进行匹配,如果没有匹配返回缺失值:
aggdict = {"column_a":3500, "column_b":8200}
dailyAgg = df.groupby(["id_col"]).agg(lambda x: (x >= aggdict.get(x.name, np.nan)).sum())
print (dailyAgg)
column_a column_b
id_col
A 1 1
B 2 0
编辑:我认为在你的解决方案中没有通过 x
组值,这里是
def prepareAggDict(p):
def ipf(x):
return (x >= p).sum()
return ipf
data = {
"id_col":["A","A","B","B","B"],
"column_a":[500,4500,8100,300,11500],
"column_b":[800,22340,7554,300,900]
}
df = pd.DataFrame(data)
d = {"column_a":3500, "column_b":8200}
aggdict = {k: prepareAggDict(v) for k, v in d.items()}
#return same like
#aggdict = {"column_a":prepareAggDict(3500), "column_b":prepareAggDict(8200)}
dailyAgg = df.groupby(["id_col"]).agg(aggdict)
print (dailyAgg)
column_a column_b
id_col
A 1 1
B 2 0