首页 > 解决方案 > dataframe.group 通过更改空数据框的 dtypes

问题描述

所以我不确定以下是否是故意的,但这似乎是我之前使用的 pandas 0.18.0 的行为变化。我已经更新到 0.23.0 并且出现了一些奇怪的行为......

假设我有一些大型数据框,被调用dfLarge并且我df根据某些标准从中获取一个子集。(这部分问题对于复制并不是真正必要的,但它来自我的实际用例以及我如何注意到熊猫行为的变化)。但碰巧我无法根据我在 中寻找的标准得到匹配dfLarge,所以df是空的。

重要的是df共享dtypes相同dfLarge。一般来说,它可能看起来像这样df

In [187]: df = pd.DataFrame(columns = ['field1','field2','field3','num1','num2'])

In [188]: df['num1'] = df['num1'].astype('float64')  # assume this was inherited from dfLarge

In [189]: df['num2'] = df['num2'].astype('float64')  # assume this was inherited from dfLarge

In [190]: df.dtypes
Out[190]:
field1     object
field2     object
field3     object
num1      float64
num2      float64
dtype: object

所以现在我们有一些字段和不同的数据类型用于空数据框df。当我聚合我的数据,同时通过对和df.groupby求和来维护我的索引时,生成的数据框会改变我的字段。field1field2dtype

In [191]: dfGrouped = df.groupby(['field1','field2'])[['num1','num2']].sum().reset_index(level=['field1','field2'])

In [192]: dfGrouped.dtypes
Out[192]:
field1     float64
field2     float64
num1       float64
num2       float64
dtype: object

据我从熊猫文档中可以看出,df.groupby不应该这样做,我只发现熊猫 0.18.0 的行为发生了变化(其中dtypes不发生变化),因为我随后在针对某些字符串TypeErrors进行了各种测试时遇到了这种变化。fields有什么办法可以优雅地处理这个问题,而不是在dtypes之前将 my 分配给一个新对象groupby并以某种方式重新应用它们df['field'] = df['field'].astype('newtype')?谢谢你。

标签: pythonpandasdataframepandas-groupby

解决方案


as_index=False指定您的groupby.

我相信这个错误是由设置和重置一个空的MultiIndexgroupby设置MultiIndex,然后你重置它)引起的。请参阅GitHub 问题跟踪器上的#19602 。Usingas_index=False可以防止这种模式的发生,因为它一开始MultiIndex就不会被设置groupby

In [2]: pd.__version__
Out[2]: '0.23.0'

In [3]: df = pd.DataFrame(columns=['field1','field2','field3','num1','num2'])
   ...: df = df.astype({'num1': 'float64', 'num2': 'float64'})

In [4]: df.dtypes
Out[4]:
field1     object
field2     object
field3     object
num1      float64
num2      float64
dtype: object

In [5]: dfGrouped = df.groupby(['field1','field2'], as_index=False)[['num1','num2']].sum()

In [6]: dfGrouped.dtypes
Out[6]:
field1     object
field2     object
num1      float64
num2      float64
dtype: object

请注意,这也应该保留非空 DataFrame 的行为:

In [7]: df = pd.DataFrame({'field1': list('aaaa'),
   ...:                    'field2': list('0101'),
   ...:                    'field3': list('wxyz'),
   ...:                    'num1': [0.0, 1.0, 2.0, 3.0],
   ...:                    'num2': [10.0, 11.0, 12.0, 13.0]})

In [8]: df
Out[8]:
  field1 field2 field3  num1  num2
0      a      0      w   0.0  10.0
1      a      1      x   1.0  11.0
2      a      0      y   2.0  12.0
3      a      1      z   3.0  13.0

In [9]: dfGrouped = df.groupby(['field1','field2'], as_index=False)[['num1','num2']].sum()

In [10]: dfGrouped.dtypes
Out[10]:
field1     object
field2     object
num1      float64
num2      float64
dtype: object

In [11]: dfGrouped
Out[11]:
  field1 field2  num1  num2
0      a      0   2.0  22.0
1      a      1   4.0  24.0

推荐阅读