pandas 在具有多种数据类型的系列上崩溃
pandas crashes on series with multiple data types
我有一个简单的 excel 文件,其中包含两列 - 一个分类列和另一个数字列,我使用 read_excel 函数读入 pandas,如下所示
df= pd.read_excel('pandas_crasher.xlsx')
第一列是多种类型的对象类型。由于 excel 格式错误,该列包含时间戳、浮点数和文本的组合。但它通常应该只是一个简单的文本列
from datetime import datetime
from collections import Counter
df['random_names'].dtype
dtype('O')
print Counter([type(i) for i in load_instance['random_names']])
Counter({type 'unicode'>: 15427, type 'datetime.datetime'>: 18,
type 'float'>: 2})
当我对其进行简单的 groupby 操作时,它 crashes the python kernel
没有任何错误消息或通知 - 我尝试通过 jupyter 和一个小型自定义烧瓶应用程序进行操作没有任何运气。
df.groupby('random_names')['random_values'].sum()
<< 崩溃
这是一个相对较小的文件,只有 700kb(15k 行和 2 列)- 所以绝对不是内存问题
我尝试使用 pdb 进行调试以跟踪崩溃点但无法通过 pandas/core/groupby.py module
中的 cython 函数
def _cython_operation(self, kind, values, how, axis)
pandas 中的一个可能错误 - 与其直接崩溃,不如抛出异常并优雅地退出?
然后我使用以下函数将各种数据类型转换为文本
def custom_converter(x):
if isinstance(x,datetime) or isinstance( x, ( int, long, float ) ):
return str(x)
else:
return x.encode('utf-8')
df['new_random_names'] = df['random_names'].apply(custom_converter)
df['new_random_names'].groupby('random_names')['random_values'].sum() << does not crash
应用自定义函数可能是执行此操作最慢的方法。有什么 better/faster 方法可以做到这一点吗?
Excel 文件在这里:https://drive.google.com/file/d/0B1ZLijGO6gbLelBXMjJWRFV3a2c/view?usp=sharing
对我来说,崩溃似乎是在 pandas 尝试对组键进行排序时发生的。如果我将 sort=False
参数传递给 .groupby()
,那么操作就会成功。这也可能对您有用。排序似乎是一个 numpy 操作,实际上并不涉及 pandas 个对象,因此它最终可能是一个 numpy 问题。 (例如,df.random_names.values.argsort()
也会让我崩溃。)
经过更多尝试后,我猜测问题与某种模糊情况有关,这种情况是由于在 numpy 的排序操作期间进行的特定比较而出现的。对我来说,这会崩溃:
df.random_names.values[14005:15447]
但是在切片的两端留下一个项目不会再崩溃了。制作此数据的副本,然后通过取出单个元素对其进行调整,是否会发生崩溃取决于是否从数据中删除了某些看似随机的元素。此外,在某些情况下它会失败,但 "TypeError: can't compare datetime.datetime to unicode"(或 "datetime to float")除外。
这部分数据包含一个日期时间和一个浮点值,正好是一个nan
。看起来 numpy 代码中有一些奇怪的边缘情况导致失败的比较在某些情况下崩溃而不是引发正确的异常。
要回答您 post 末尾的问题,您可能会更轻松地使用 read_excel
的各种参数(例如 converters
参数)来阅读所有内容数据从一开始就作为文本值。
我有一个简单的 excel 文件,其中包含两列 - 一个分类列和另一个数字列,我使用 read_excel 函数读入 pandas,如下所示
df= pd.read_excel('pandas_crasher.xlsx')
第一列是多种类型的对象类型。由于 excel 格式错误,该列包含时间戳、浮点数和文本的组合。但它通常应该只是一个简单的文本列
from datetime import datetime
from collections import Counter
df['random_names'].dtype
dtype('O')
print Counter([type(i) for i in load_instance['random_names']])
Counter({type 'unicode'>: 15427, type 'datetime.datetime'>: 18, type 'float'>: 2})
当我对其进行简单的 groupby 操作时,它 crashes the python kernel
没有任何错误消息或通知 - 我尝试通过 jupyter 和一个小型自定义烧瓶应用程序进行操作没有任何运气。
df.groupby('random_names')['random_values'].sum()
<< 崩溃
这是一个相对较小的文件,只有 700kb(15k 行和 2 列)- 所以绝对不是内存问题
我尝试使用 pdb 进行调试以跟踪崩溃点但无法通过 pandas/core/groupby.py module
中的 cython 函数def _cython_operation(self, kind, values, how, axis)
pandas 中的一个可能错误 - 与其直接崩溃,不如抛出异常并优雅地退出?
然后我使用以下函数将各种数据类型转换为文本
def custom_converter(x):
if isinstance(x,datetime) or isinstance( x, ( int, long, float ) ):
return str(x)
else:
return x.encode('utf-8')
df['new_random_names'] = df['random_names'].apply(custom_converter)
df['new_random_names'].groupby('random_names')['random_values'].sum() << does not crash
应用自定义函数可能是执行此操作最慢的方法。有什么 better/faster 方法可以做到这一点吗?
Excel 文件在这里:https://drive.google.com/file/d/0B1ZLijGO6gbLelBXMjJWRFV3a2c/view?usp=sharing
对我来说,崩溃似乎是在 pandas 尝试对组键进行排序时发生的。如果我将 sort=False
参数传递给 .groupby()
,那么操作就会成功。这也可能对您有用。排序似乎是一个 numpy 操作,实际上并不涉及 pandas 个对象,因此它最终可能是一个 numpy 问题。 (例如,df.random_names.values.argsort()
也会让我崩溃。)
经过更多尝试后,我猜测问题与某种模糊情况有关,这种情况是由于在 numpy 的排序操作期间进行的特定比较而出现的。对我来说,这会崩溃:
df.random_names.values[14005:15447]
但是在切片的两端留下一个项目不会再崩溃了。制作此数据的副本,然后通过取出单个元素对其进行调整,是否会发生崩溃取决于是否从数据中删除了某些看似随机的元素。此外,在某些情况下它会失败,但 "TypeError: can't compare datetime.datetime to unicode"(或 "datetime to float")除外。
这部分数据包含一个日期时间和一个浮点值,正好是一个nan
。看起来 numpy 代码中有一些奇怪的边缘情况导致失败的比较在某些情况下崩溃而不是引发正确的异常。
要回答您 post 末尾的问题,您可能会更轻松地使用 read_excel
的各种参数(例如 converters
参数)来阅读所有内容数据从一开始就作为文本值。