DataFrame 性能警告

Posted

技术标签:

【中文标题】DataFrame 性能警告【英文标题】:DataFrame performance warning 【发布时间】:2018-09-17 16:21:24 【问题描述】:

我收到来自 Pandas 的性能警告

/usr/local/lib/python3.4/dist-packages/pandas/core/generic.py:1471: 
PerformanceWarning: 
your performance may suffer as PyTables will pickle object types that it cannot
map directly to c-types [inferred_type->mixed-integer,key->block0_values] [items->['int', 'str']]

我在 github 上阅读了几期和这里的问题,他们都说这是因为我在一列中混合了类型,但我绝对不是。简单的例子如下:

import pandas as pd
df = pd.DataFrame(columns=['int', 'str'])
df = df.append( 'int': 0, 'str': '0', ignore_index=True)
df = df.append( 'int': 1, 'str': '1', ignore_index=True)
for _, row in df.iterrows():
   print(type(row['int']), type(row['str']))

# <class 'int'> <class 'str'>
# <class 'int'> <class 'str'>

# however
df.dtypes
# int    object
# str    object
# dtype: object

# the following causes the warning
df.to_hdf('table.h5', 'table')

这是怎么回事?我该怎么办?

【问题讨论】:

您是否尝试过将数字列转换为数字?例如,df[col] = df[col].astype(int)? @jpp 哇!而已!谢谢!我只是有点缺乏经验,不知道它是必需的还是一个把戏? 见下面的答案。 【参考方案1】:

您需要在适当的情况下将数据框系列转换为数字类型。

对于整数有两种主要的实现方式:

# Method 1
df['col'] = df['col'].astype(int)

# Method 2
df['col'] = pd.to_numeric(df['col'], downcast='integer')

这可确保数据类型被适当地映射到 C 类型,从而使数据能够以 HDF5 格式(PyTables 使用)存储,而无需进行酸洗。

【讨论】:

【参考方案2】:

在@jpp 的回答的基础上,我在自己的数据中将此问题追踪到在将大型 CSV 加载到 pandas 数据框时默认使用 int64float64 数据类型。

解决方法:

for c in df.columns[df.dtypes=='float64'].values:
        df[c] = df[c].astype('float')
    
    for c in df.columns[df.dtypes=='int64'].values:
        df[c] = df[c].astype('int')

现在可以导出到 HDF 而不会出现警告。当然,您可以自动执行此操作,但就我而言,这已经“足够好”了。

【讨论】:

以上是关于DataFrame 性能警告的主要内容,如果未能解决你的问题,请参考以下文章

pandas DataFrame 警告(SettingWithCopyWarning)

Pandas - DataFrame reindex 函数返回警告

pandas DataFrame 警告(SettingWithCopyWarning)

pandas 报警告:A value is trying to be set on a copy of a slice from a DataFrame

如何遍历大型 Pyspark Dataframe 中列的不同值? .distinct().collect() 引发大任务警告

当列是现有列的布尔测试时,为啥向 Pandas DataFrame 添加列会返回 SettingWithCopy 警告?