Pandas DataFrame列数据类型df.TT!= df?

Joo*_*oop 0 python pandas

一般问题,但我已经使用熊猫超过一年了,当我在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中的列没有一致的数据类型时,我应该注意什么?

Jef*_*eff 6

数据类型是基于列的.df.T在混合类型框架中进行转置,必然会转换为可以包含两种类型的类型,这意味着字符串和float将产生objectdtype.

所以df.T.T != df,但是,你可以这样做:df.T.T.convert_objects()这通常会成功地将objectdtypes 转换回基本类型.


unu*_*tbu 5

在引擎盖下,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)