dataframe.groupby 更改空数据框的 dtypes

jbo*_*xxx 4 python dataframe pandas pandas-groupby

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

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

什么是重要的是,df共享相同dtypesdfLarge。一般来说,对于某些人来说可能是这样的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
Run Code Online (Sandbox Code Playgroud)

所以现在我们有一个空数据框的一些字段和不同的数据类型df。当我df.groupby通过对field1和求和来维护我的索引的同时使用聚合我的数据时field2,结果数据dtype框会更改我的字段。

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
Run Code Online (Sandbox Code Playgroud)

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

roo*_*oot 5

使用as_index=False指定你的时候groupby

我相信这个错误是由设置和重置空值引起的MultiIndexgroupby设置MultiIndex,然后重置它)。请参阅GitHub 问题跟踪器上的#19602。使用as_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
Run Code Online (Sandbox Code Playgroud)

请注意,这也应该保留非空 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
Run Code Online (Sandbox Code Playgroud)