pandas读框和后续的类型操作问题

时间:2014-12-05 18:47:22

标签: python datetime pandas

你好我是一个有熊猫的新手,有特殊的行为,我想知道

的原因
sqlnew = 'select FUND_NO,START_DATE,END_DATE,CASH,BOND,SMALL_CAP,LARGE_CAP,INTERNATIONAL from ODSACT.ACT_SRC_FUND_MAPPING;'
ActualFundMapping = psql.read_frame(sqlnew,cnxn)

'Everyworks罚款直至上述'

ActualFundMapping.dtypes::

FUND_NO           object
START_DATE        object
END_DATE          object
CASH             float64
BOND             float64
SMALL_CAP        float64
LARGE_CAP        float64
INTERNATIONAL    float64

'因为我想在ActualFundMapping ['START_DATE']中添加类似datetime.datetime(2013,1,1)的内容,我尝试更改dtype,如下所示

ActualFundMapping['START_DATE'] = pd.to_datetime(str(ActualFundMapping['START_DATE']))
ActualFundMapping['END_DATE'] = pd.to_datetime(str(ActualFundMapping['END_DATE']))
ActualFundMapping['FUND_NO'] = ActualFundMapping['FUND_NO'].astype(np.int64)

'但存在测试会回来假

datetime.datetime(2012,1,1) in ActualFundMapping['START_DATE']
False

“该条目存在于sql表中,我已经验证了它

其中

str(datetime.datetime(2012,1,1)) in str(ActualFundMapping['START_DATE'])
True

'同样的问题重复以下

np.int64(1000) in ActualFundMapping['FUND_NO']
False

我想我不理解熊猫在内部使用的表示。非常感谢任何帮助。

******* ******* UPDATE

根据进一步的建议,我将sql表的START_DATE列作为数据帧的索引列。

ActualFundMapping = psql.read_frame(sqlnew,cnxn,'START_DATE')

ActualFundMapping.index
[2012-01-01 00:00:00,...,2012-01-01 00:00:00]
长度:895,频率:无,时区:无

datetime.datetime(2012,1,1) in ActualFundMapping
False

datetime.datetime(2012,1,1) in ActualFundMapping.index

错误

np.datetime64(datetime.datetime(2012,1,1)) in ActualFundMapping.index

2 个答案:

答案 0 :(得分:0)

通过执行str(ActualFundMapping['START_DATE']),您将整个列转换为单个字符串。我相信pandas将字符串存储为dtype object(以避免使用numpy字符串dtypes时出现的截断问题)。尝试使用pd.to_datetime(ActualFundMapping['START_DATE'])。如果它引发错误,那么列中可能存在混合类型数据,您将不得不做更多的侦探工作来确定哪些单个值导致问题。

正如unutbu建议的那样,您还需要确保检查系列值的成员资格,而不是索引。

答案 1 :(得分:0)

使用时

value in df['START_DATE']

Pandas调用df['START_DATE'].__contains__(value),如您所见from the source code,测试value是否在信息轴(即系列索引)。 那不是我们想要的。

有很多方法可以解决这个问题。例如,

df = pd.DataFrame({'START_DATE':[DT.datetime(2013,1,1)] 
                   , 'FUND_NO': np.array([1000], dtype=np.int64)})

创建DatetimeIndex并调用DatetimeIndex.__contains__

In [94]: DT.datetime(2013,1,1) in pd.DatetimeIndex(df['START_DATE'])
Out[94]: True

创建一个布尔掩码,然后调用any()

In [102]: (df['START_DATE'] == DT.date(2013,1,1)).any()
Out[102]: True

下拉到NumPy datetime64s并使用ndarray.__contains__

In [126]: np.array(DT.datetime(2013,1,1), dtype='<M8[ns]') in df['START_DATE'].values
Out[126]: True

同样地,1000 in df['FUND_NO']无法正常工作,因为如果1000位于df['FUND_NO']的索引中,则会再次测试。解决方法包括:

In [96]: (df['FUND_NO'] == 1000).any()
Out[96]: True

In [127]: 1000 in df['FUND_NO'].values
Out[127]: True