jbo*_*xxx 4 python dataframe pandas pandas-groupby
所以我不确定以下内容本身是否是故意的,但这似乎是我之前使用的 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
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')
方式重新应用它们?谢谢你。
使用as_index=False
指定你的时候groupby
。
我相信这个错误是由设置和重置空值引起的MultiIndex
(groupby
设置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)