【问题标题】:HDFStore with string columns gives issues带有字符串列的 HDFStore 会出现问题
【发布时间】:2014-05-24 19:09:49
【问题描述】:

我有一个 pandas DataFrame myDF 有几个字符串列(其 dtypeobject)和许多数字列。我尝试了以下方法:

d=pandas.HDFStore("C:\\PF\\Temp.h5")
d['test']=myDF

我得到了这个结果:

C:\PF\WinPython-64bit-3.3.3.3\python-3.3.3.amd64\lib\site-packages\pandas\io\pytables.py:2446: PerformanceWarning: 

your performance may suffer as PyTables will pickle object types that it cannot
map directly to c-types [inferred_type->mixed,key->block2_values] 
[items->[0, 1, 3, 4, 5, 6, 9, 10, 292, ...]]

warnings.warn(ws, PerformanceWarning)

似乎每个字符串列都会出现问题。例如,如果我尝试

myDF[0].dtype

我明白了

Out[38]: dtype('O')

如何解决此问题,即更改字符串列的 dtype 以便 HDFStore 可以将其视为字符串列?


编辑

根据要求提供更多信息

>>> pandas.__version__
Out[49]: '0.13.1'

>>> tables.__version__
Out[53]: '3.1.0'

如下构建pandas数据框:

pandas.read_csv(fName,sep="|",header=None, low_memory=False)

当我尝试时

myDF.info()

我明白了

Int64Index: 153895 entries, 0 to 153894
Data columns (total 644 columns):
0      object
1      object
2      int64
3      object
4      object
5      object
6      object
7      int64
8      float64
9      object
10     object
11     float64
12     float64
...
...
642    float64
643    float64
dtypes: float64(619), int64(2), object(23)

所有字符串列都被读取为object

【问题讨论】:

  • 你能显示pandas版本、pytables版本、os、df.info()、df是如何构建的,还有一个示例
  • 你为什么要传递low_memory?你有任何字符串中的 unicode 吗?
  • 因为文件太大,而且没有low_memory 似乎不起作用。这是错误C:\PF\WinPython-64bit-3.3.3.3\python-3.3.3.amd64\lib\site-packages\pandas\io\parsers.py:1070: DtypeWarning: Columns (6,292,479,572,581,590,599,608,617,626,635) have mixed types. Specify dtype option on import or set low_memory=False. data = self._reader.read(nrows)
  • 好的,你是 32 位的吗?按块读取,并创建一个table 存储。
  • 不,我是 64 位的。见上面的错误。另外,table 商店是什么意思?

标签: python-3.x pandas pytables


【解决方案1】:

仅当您在列中有混合类型时才会出现此警告。不仅仅是字符串,还有字符串 AND 数字。

In [2]: DataFrame({ 'A' : [1.0,'foo'] }).to_hdf('test.h5','df',mode='w')
pandas/io/pytables.py:2439: PerformanceWarning: 
your performance may suffer as PyTables will pickle object types that it cannot
map directly to c-types [inferred_type->mixed,key->block0_values] [items->['A']]

  warnings.warn(ws, PerformanceWarning)

In [3]: df = DataFrame({ 'A' : [1.0,'foo'] })

In [4]: df
Out[4]: 
     A
0    1
1  foo

[2 rows x 1 columns]

In [5]: df.dtypes
Out[5]: 
A    object
dtype: object

In [6]: df['A']
Out[6]: 
0      1
1    foo
Name: A, dtype: object

In [7]: df['A'].values
Out[7]: array([1.0, 'foo'], dtype=object)

因此,您需要确保不要在列内混合

如果您有需要转换的列,您可以这样做:

In [9]: columns = ['A']

In [10]: df.loc[:,columns] = df[columns].applymap(str)

In [11]: df
Out[11]: 
     A
0  1.0
1  foo

[2 rows x 1 columns]

In [12]: df['A'].values
Out[12]: array(['1.0', 'foo'], dtype=object)

【讨论】:

  • read_csv 中是否有任何选项可以指定它在任何列显示为 MIXED 时将其视为字符串?
  • 我尝试了df.loc[:,columns] = df[columns].applymap(str),但它并没有将我的dtypeobject 更改为字符串。即使在您的示例中,dtype 也不会从 object 更改为字符串
  • dtype 不会改变,它仍然是object。嵌入的值将是字符串。那就是问题所在。在您正在读取的数据中,嵌入的对象是浮点数/整数(实际的 Python 对象),而不是字符串。所以当框架被写入存储时,它们是对象而不是字符串(这就是你收到警告的原因)
  • 对于空格或 NaN,这会将 nan 输出为实际显示在文件中的字符串(不需要)。我应该用 np.nan 替换那些还是会导致该列再次成为对象?或者我应该使用 fillna('Blank') 还是什么?看起来这会占用空间,但我又有很多空间。
猜你喜欢
  • 2023-03-30
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多