一般问题,但我已经使用熊猫超过一年了,当我在pandas DataFrame列中混合类型时,我一直遇到麻烦.我经常会有一个像这样的DataFrame:
df2 =
0 1 2 3 4
val_str test test test test test
val_date 2014-01-15 2014-01-15 2014-01-15 2014-01-15 2014-01-15
val_float 1.5 1.5 1.5 1.5 1.5
val_int 1 1 1 1 1
Run Code Online (Sandbox Code Playgroud)
作为示例生成:
import pandas as pd
import datetime
df = pd.DataFrame(index=range(5))
df['val_str'] = "test"
df['val_date']= datetime.datetime(2014,1,15)
df['val_bool'] = True
df['val_float'] = 1.5
df['val_int'] = 1
df2=df.T
Run Code Online (Sandbox Code Playgroud)
令人费解的例子,但数据来自excel,csv等,并且很多时候行具有一致的数据类型而不是列.
Pandas似乎(大多数情况下)使用这种数据来处理它的方法,但是在选择或尝试对数据进行布尔运算时,我经常得到意想不到的结果.
用例如选择数据
df2[2]['val_bool'] #eems to work without problem
Run Code Online (Sandbox Code Playgroud)
似乎工作得很好,甚至用例如:
df2.ix['val_bool'] # works fine
Run Code Online (Sandbox Code Playgroud)
似乎按预期工作.尝试使用此切片进一步选择数据时,我经常遇到问题.
df2.ix['val_bool'].dtype
>>> dtype('O')
# trying boolean operations on this gives numeric results?
Run Code Online (Sandbox Code Playgroud)
关于这是否会引起问题,是否有任何熊猫指南?我已经回到一些初始教程并收集了列"应该"具有一致的数据类型.然而,熊猫的灵活性允许你这样做,但有些方法会破坏吗?我依稀记得Wes McKinneys的一次谈话,他提到:
df.T.T != df
Run Code Online (Sandbox Code Playgroud)
有什么区别,当DataFrame中的列没有一致的数据类型时,我应该注意什么?
数据类型是基于列的.df.T在混合类型框架中进行转置,必然会转换为可以包含两种类型的类型,这意味着字符串和float将产生objectdtype.
所以df.T.T != df,但是,你可以这样做:df.T.T.convert_objects()这通常会成功地将objectdtypes 转换回基本类型.
在引擎盖下,Pandas在块中存储具有相同dtype的列或列组.因此,您可以将所有浮点列存储在一个大数组中,将所有字符串列存储在另一个数组中,等等.
如果有异构列数据(df2如上所述),则每个值都存储在dtype数组中object:
In [154]: df2._data
Out[154]:
BlockManager
Items: Int64Index([0, 1, 2, 3, 4], dtype='int64')
Axis 1: Index([u'val_str', u'val_date', u'val_bool', u'val_float', u'val_int'], dtype='object')
ObjectBlock: [0, 1, 2, 3, 4], 5 x 5, dtype: object
Run Code Online (Sandbox Code Playgroud)
这是最糟糕的dtype,因为它没有NumPy数字类型提供的速度优势.此外,一些NumPy(可能还有Pandas)函数在对象dtype数组上运行时会引发异常.
即使选择只有浮点值的行,也会返回一个对象dtype数组:
In [149]: df2.loc['val_float'].dtype
Out[149]: dtype('O')
Run Code Online (Sandbox Code Playgroud)
因此,利用pandas的最佳方法是以一种允许整列具有NumPy dtypes object而不是转换的方式加载数据(除非整个DataFrame是同类dtype).
注意如何将列df分隔成不同dtype的块.这比df2一个人大得多ObjectBlock.
In [155]: df._data
Out[155]:
BlockManager
Items: Index([u'val_str', u'val_date', u'val_bool', u'val_float', u'val_int'], dtype='object')
Axis 1: Int64Index([0, 1, 2, 3, 4], dtype='int64')
ObjectBlock: [val_str], 1 x 5, dtype: object
DatetimeBlock: [val_date], 1 x 5, dtype: datetime64[ns]
BoolBlock: [val_bool], 1 x 5, dtype: bool
FloatBlock: [val_float], 1 x 5, dtype: float64
IntBlock: [val_int], 1 x 5, dtype: int64
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |