当前位置: 首页 > 知识库问答 >
问题:

Pandas GroupBy.apply方法复制第一个组

孙承弼
2023-03-14

我的第一个SO问题:我对pandas(0.12.0-4)中groupby的apply方法的这种行为感到困惑,它似乎对数据帧的第一行应用了两次函数。例如:

>>> from pandas import Series, DataFrame
>>> import pandas as pd
>>> df = pd.DataFrame({'class': ['A', 'B', 'C'], 'count':[1,0,2]})
>>> print(df)
   class  count  
0     A      1  
1     B      0    
2     C      2

我首先检查groupby函数是否正常工作,它似乎很好:

>>> for group in df.groupby('class', group_keys = True):
>>>     print(group)
('A',   class  count
0     A      1)
('B',   class  count
1     B      0)
('C',   class  count
2     C      2)

然后,我尝试在Groupby对象上使用应用程序做类似的事情,并两次获得第一行输出:

>>> def checkit(group):
>>>     print(group)
>>> df.groupby('class', group_keys = True).apply(checkit)
  class  count
0     A      1
  class  count
0     A      1
  class  count
1     B      0
  class  count
2     C      2

任何帮助都将不胜感激!谢谢

编辑:@Jeff在下面提供了答案。我很密集,没有立即理解它,所以这里有一个简单的例子来说明,尽管上面的例子中第一个组有两次打印输出,应用方法在第一个组上只操作一次,并且不会改变原始数据帧:

>>> def addone(group):
>>>     group['count'] += 1
>>>     return group

>>> df.groupby('class', group_keys = True).apply(addone)
>>> print(df)

      class  count
0     A      1
1     B      0
2     C      2

但是通过将方法的返回分配给一个新对象,我们可以看到它按预期工作:

>>> df2 = df.groupby('class', group_keys = True).apply(addone)
>>> print(df2)

      class  count
0     A      2
1     B      1
2     C      3

共有3个答案

马浩淼
2023-03-14

您可以使用for循环来避免groupby.apply重复的第一行,

log_sample.csv

guestid,keyword
1,null
2,null
2,null
3,null
3,null
3,null
4,null
4,null
4,null
4,null

我的代码片段

df=pd.read_csv("log_sample.csv") 
grouped = df.groupby("guestid")

for guestid, df_group in grouped:
    print(list(df_group['guestid'])) 

df.head(100)

输出

[1]
[2, 2]
[3, 3, 3]
[4, 4, 4, 4]
左丘恩
2023-03-14

从v0.25开始,GroupBy.apply()。见GH24748。

0.25.0(2019年7月18日)的新功能是:Groupby.onDataFrame仅对第一组进行一次计算

文件中的相关示例:

pd.__version__                                                                                                          
# '0.25.0.dev0+590.g44d5498d8'

df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})                                                                      

def func(group): 
    print(group.name) 
    return group                                                                                                                     

新行为

df.groupby('a').apply(func)                                                                                            
x
y

   a  b
0  x  1
1  y  2

旧行为(

df.groupby('a').apply(func)
x
x
y

   a  b
0  x  1
1  y  2

Pandas仍然使用第一组来确定apply是否可以采用快速路径。但至少它不再需要对第一组进行两次评估。干得好,开发人员!

贲宏硕
2023-03-14

这是经过设计的正如这里和这里所描述的

apply函数需要知道返回数据的形状,以便智能地确定如何组合这些数据。要做到这一点,它会调用函数两次(在您的例子中是checkit)。

根据您的实际用例,您可以用聚合、转换或过滤来替换对应用的调用,如下文所述。这些函数要求返回值为特定形状,因此不要两次调用该函数。

但是,如果您正在调用的函数没有副作用,那么在第一个值上调用函数两次很可能无关紧要。

 类似资料:
  • 问题内容: 我的第一个SO问题:我对在熊猫(0.12.0-4)中groupby的apply方法的这种行为感到困惑,它似乎将TWICE函数应用于数据帧的第一行。例如: 我首先检查groupby函数是否可以正常工作,这似乎很好: 然后,我尝试对groupby对象应用apply来执行类似的操作,并且两次获得第一行输出: 任何帮助,将不胜感激!谢谢。 编辑:@Jeff提供以下答案。我很忙,并没有立即理解它

  • 问题内容: 我知道有,但仅适用于覆盖其他方法的方法。 我有几个带有许多 委托 方法的类(它们 不会 覆盖其他方法)。 他们的Javadoc是否可以“继承”(更确切地说是复制)? 问题答案: @link或@see标记在这里比较合适。如果要包装该方法,则它必须提供独特的行为,这使其不适用于重载或其他情况。

  • 问题内容: 当我运行以下代码时,什么也不会被复制-我在做什么错? 另外,这是将数据从一个阵列复制到另一个阵列的最佳/最有效的方法吗? 问题答案: 我认为您的工作很落后: 应该:

  • 因此,我正在编写一个有两个面板的文件管理器(就像Total Commander一样)。我试图将3个主要的云提供商(GDrive、Dropbox、OneDrive)集成到其中。我正在用C#(WPF)编写这个文件管理器,并尝试使用官方SDK。其中一个特性是可以将文件和文件夹从一个云复制到另一个云,所以就像GDrive在左边面板上,Dropbox在右边面板上,从GDrive复制到Dropbox。 有没有

  • 第一个控制器 The Controllers layer is responsible for handling incoming HTTP requests. In Nest, Controller is a simple class with @Controller() decorator. 控制层负责处理传入的HTTP请求。在Nest中,控制器是一个带有@Controller()装饰器的类。

  • 请帮助我理解以下问题: 从 https://alligator.io/vuejs/common-gotchas/ “您不能直接向根数据对象添加新属性,但可以使用”: Vue.set(this.data, “道具名称”, 值) Vue.set(this.$data,'lastAddedName','John Elway'); 但是 Vue.set() 上面的方法中的第一个参数:“this.data”