python 字典理解如何与内部的 lambda 函数一起工作

2024-01-31

我的目标是使用以下方法聚合 pandas DataFrameGroupBy 对象agg https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.aggregate.html功能。

为了做到这一点,我正在生成一个字典,我将使用 dict 解包将其解包为 kwargs**dict。该字典需要包含新列名作为键和元组作为值。元组的第一个值是列名,该列名被压缩为一个系列,并作为第二个值的输入lambda series: ....

agg_dict = {
   f"{cat_name}_count": ('movement_state', lambda series: series.value_counts()[cat_name]) 
   for cat_name in ml_data['category_column'].cat.categories
}

# Aggregating
agg_ml_data = ml_data.groupby(['col1', 'col2']).agg(**agg_dict)

现在实际发生的事情对我来说有点奇怪。

假设:

ml_data['category_column'].cat.categories
Index(['cat1', 'cat2', 'cat3'], dtype='object')

一组的正确值计数是

one_group['category_column'].value_counts()
     | category_column
cat1 | 2
cat2 | 9
cat3 | 6

一组的预期输出:

cat1_count cat2_count cat3_count
2 9 6

一组的实际输出

cat1_count cat2_count cat3_count
6 6 6

不知何故,python 执行 lambda 函数的 dict 理解并不像预期的那样,并且仅使用最后一个类别值cat3索引时series.value_counts()[cat_name]。我希望 lambda 函数是像字典本身一样创建的。关于如何解决这个问题有什么想法吗?


这是一个经典的Python陷阱。

当您使用自由变量时(cat_name,在本例中)在 lambda 表达式中,lambda 捕获名称指的是哪个变量,而不是该变量的值。所以在这种情况下,lambda“记住”cat_name是“该字典理解的循环变量”。当调用 lambda 时,它会查找“该字典理解的循环变量”的值,现在,由于字典理解已经完成,该值仍保留在列表的最后一个值。

解决此问题的通常方法是使用默认参数来“冻结”该值,例如

lambda series, cat=cat_name: series.blah[cat]

有效地使用一个陷阱(Python 在函数定义时计算默认参数)来爬出另一个陷阱。 :-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python 字典理解如何与内部的 lambda 函数一起工作 的相关文章

随机推荐