首页 > 解决方案 > Wired Pandas DataFrame Groupby 应用行为

问题描述

我正面临一个让我发疯的问题。这是关于对 pandas 数据框进行分组并使用 apply 将(自定义)函数应用于创建的组:

df.groupby([...]).apply(somefunc)

这完全是关于数据帧 (df) 和传递给sumefunc每个组的索引。为了说明这一点,我创建了下面的示例,其中我们仅将每个组 ( groupdf) 的数据帧和索引 ( ) 存储为由 初始化index的虚拟类的属性。看起来,传递给每个组的数据框实例总是相同的,只是它的内容发生了变化(参见正文中的代码版本 v1)。SomeClassgroupby.applysomefuncSomeClass

现在,为了防止下一组覆盖前一组数据帧的内容,我只是对其进行了深度复制(SomeClass代码版本v2)。现在发生的是,df 本身很好(之前组的 df 不会被覆盖。但是,dfs 的索引仍然会被覆盖。

如果我们也对索引进行深度复制,索引本身就很好(代码版本 v3),但仍然会覆盖 df get 的索引。

有人可以解释这里发生了什么吗?groupby.apply 如何为各个组创建 dfs、索引等?

非常感谢您提前提供的帮助!万事如意,保持健康 ;) blch

PS:蟒蛇3.8.3,熊猫1.1.5。抱歉,我从头开始重写了整个问题。

PPS:我问过的一位同事刚刚调查了一下。我们可以通过在 SomeClass 中重置索引来修复 hte 索引的覆盖以及 df 的覆盖,即添加一行groupdf = groupdf.reset_index().rename(columns={'index': 'the_index'})。然后,“旧”索引可以作为正确的列通过groupdf.the_index. 所以这或多或少地创建了一个全新的 df 和一个新的索引,这两个索引都不会被覆盖 ... 。我仍然不太明白如何groupby.apply创建组 dataframes groupdf

(复制过去的例子)

df = pd.DataFrame([1,1,2], columns=['a'])

print(df)
print()


class SomeClass():
    def __init__(self, groupdf):
        ###
        # v1, no copy:
        #self.groupdf = groupdf
        #self.index  = groupdf.index
        
        # v2, df deep copy:
        #groupdf = groupdf.copy(deep=True)
        #self.groupdf = groupdf
        #self.index  = groupdf.index
        
        # v3, df and index copy:
        self.groupdf = groupdf.copy(deep=True)
        self.index  = groupdf.index.copy(deep=True)
        
        ###
        print('  DF ID', id(self.groupdf))
        print('  index ID', id(self.index))
        print('  SomeClassNoCopy: I got a df with index {}'.format(self.index))
        print(self.groupdf)
        print()

print('Created Groups:')
gps = df.groupby(['a']).apply(lambda gdf: SomeClass(gdf))


print('\nStored groups:')
for v in gps:
    print('  SomeClassNoCopy: df with index {}'.format(v.index))
    print(v.groupdf) # <---- This is throwing an error for v1 for whatever reason ...


# results of v1: #######################################################

   a
0  1
1  1
2  2

#Created Groups:
#  DF ID 139909079825616
#  index ID 139909079824464
#  SomeClassNoCopy: I got a df with index Int64Index([0, 1], dtype='int64')   
   a
0  1
1  1

#  DF ID 139909079825616
#  index ID 139909079824464
#  SomeClassNoCopy: I got a df with index Int64Index([2], dtype='int64')
   a
2  2


#Stored groups:
#  SomeClassNoCopy: df with index Int64Index([2], dtype='int64')
#  SomeClassNoCopy: df with index Int64Index([2], dtype='int64')

# results of v2: ########################################################
#Created Groups:
#  DF ID 139909079823648
#  index ID 139909079825424
#  SomeClassNoCopy: I got a df with index Int64Index([0, 1], dtype='int64')
   a
0  1
1  1

#  DF ID 139909079822928
#  index ID 139909092171200
#  SomeClassNoCopy: I got a df with index Int64Index([2], dtype='int64')
   a
2  2


#Stored groups:
#  SomeClassNoCopy: df with index Int64Index([2], dtype='int64')
   a
2  1    # <--- the index should be 0,1 just like when the group was greated
   1
#  SomeClassNoCopy: df with index Int64Index([2], dtype='int64')
   a
2  2

# results of v3: ########################################################
#Created Groups:
#  DF ID 139909092169808
#  index ID 139909092169136
#  SomeClassNoCopy: I got a df with index Int64Index([0, 1], dtype='int64')
   a
0  1
1  1

#  DF ID 139909092170720
#  index ID 139909079823024
#  SomeClassNoCopy: I got a df with index Int64Index([2], dtype='int64')
   a
2  2


#Stored groups:
#  SomeClassNoCopy: df with index Int64Index([0, 1], dtype='int64')
   a                                            A
2  1  # < the index of that df differs from ----| this index
   1
#  SomeClassNoCopy: df with index Int64Index([2], dtype='int64')
   a
2  2

标签: pythonpython-3.xpandasdataframepandas-groupby

解决方案


推荐阅读