Groupby是使用Pandas进行数据处理时常用的函数,功能强大。特别是在group后还能跟上apply函数对数据自定义的进行转换,实在是非常方便。但有时候我们会发现,apply可能返回的数据类型有两种,为什么会这样呢?
注意:我这里用的是apply的返回值,而不是groupby的返回值。因为groupby的返回值类型其实是一个确定的:DataFrameGroupBy 对象。在 DataFrameGroupBy 对象上继续调用apply时才可能会返回不同的数据类型。
认识GroupBy及其返回值
我们先来看代码,假设有一个 DataFrame, 包含 key, v1, v2 三列:
1 | data = { |
如果从控制台输出这个 DataFrame, 我们能看到如下的二维表形式:
1 | key v1 v2 |
现在,我们以”key”为分组条件进行分组, 可以得到一个 DataFrameGroupBy 对象, 如果我们再接着取该分组对象的属性 groups ,可以得到包含的分组详情
1 | g = f.groupby(['key']) |
输出如下:
1 | <class 'pandas.core.groupby.generic.DataFrameGroupBy'> |
可以看到,DataFrameGroupBy 这个对象其实时包含了分类的条件和每个条件对应数据项在 DataFrame 中的索引。
Apply的返回值
我们来看一下运用不同的 lambda 表达式时,不同的返回值(类型)
代码1:
1 | r = g.apply(lambda x: x.v1 + 1) |
输出1:
1 | <class 'pandas.core.series.Series'> |
可以看到,现在返回的是 Series
代码2:
1 | r1 = g.apply(lambda x: x.v1 + x.v2) |
输出2:
1 | <class 'pandas.core.series.Series'> |
可以看到,返回仍然还是 Series
代码3:
1 | r2 = g.apply(lambda x: x[1:3]) |
输出3:
1 | <class 'pandas.core.frame.DataFrame'> |
可以看到,这次返回时 DataFrame 了。
如果我们比较一下上面的三段代码就会发现,apply函数的返回值类型其实时依赖与 lambda 表达式返回值的。 当 lambda 返回的是一列值是,会包装为 Series, 当返回值是多列时,会包装为 DataFrame。
将Series转换为DataFrame
直接用 Series 提供的方法 to_frame() 就可以对结果进行转换, 代码如下:
1 | r4 = g.apply(lambda x: x.v1 + 1).to_frame() |
参考输出:
1 | <class 'pandas.core.frame.DataFrame'> |
比较上面的”输出1”的结果, 可以看到数据是一致的,只是类型由 Series 转换为 DataFrame。