Python 向timedelta转换数据帧失败,带loc

Python 向timedelta转换数据帧失败,带loc,python,python-2.7,pandas,casting,Python,Python 2.7,Pandas,Casting,我有一点奇怪的情况,我不明白为什么它在一种情况下有效而在另一种情况下无效 我试图在多索引上强制转换一列,从timedelta64[ns]到timedelta64[s],我还有一个行的多索引。 如果tuple是我想要的列级别为0,级别为1: 它与df[tuple]=df[tuple].astypetimedelta64[s]一起工作 它不适用于df.loc[:,tuple].astypetimedelta64[s] 以下是一些示例数据: Level_0,,,Respondent,Responden

我有一点奇怪的情况,我不明白为什么它在一种情况下有效而在另一种情况下无效

我试图在多索引上强制转换一列,从timedelta64[ns]到timedelta64[s],我还有一个行的多索引。 如果tuple是我想要的列级别为0,级别为1:

它与df[tuple]=df[tuple].astypetimedelta64[s]一起工作

它不适用于df.loc[:,tuple].astypetimedelta64[s]

以下是一些示例数据:

Level_0,,,Respondent,Respondent,Respondent,OtherCat,OtherCat
Level_1,,,Something,StartDate,EndDate,Yes/No,SomethingElse
Region,Site,RespondentID,,,,,
Region_1,Site_1,3987227376,A,5/25/2015 10:59,5/25/2015 11:22,Yes,
Region_1,Site_1,3980680971,A,5/21/2015 9:40,5/21/2015 9:52,Yes,Yes
Region_1,Site_2,3977723249,A,5/20/2015 8:27,5/20/2015 8:41,Yes,
Region_1,Site_2,3977723089,A,5/20/2015 8:33,5/20/2015 9:09,Yes,No
加载以下内容:

In [1]: df = pd.read_csv(header=[0,1], index_col=[0,1,2])
        df

Out[1]: 
我想创建一个列Duration,然后创建一个名为DurationMinutes的列Duration除以60

我首先将日期转换为datetime:

In [2]: 

df.loc[:,('Respondent','StartDate')] = pd.to_datetime(sample.loc[:,('Respondent','StartDate')])

df.loc[:,('Respondent','EndDate')] = pd.to_datetime(df.loc[:,('Respondent','EndDate')])
df.loc[:,('Respondent','Duration')] = df.loc[:,('Respondent','EndDate')] - df.loc[:,('Respondent','StartDate')]
这就是我不明白发生了什么的地方。我想将其转换为timedelta64[s],因为我需要它。 如果我只显示astype'timedelta64[s]的结果,它就像一个符咒:

In [3]: df.loc[:,('Respondent','Duration')].astype('timedelta64[s]')
Out[3]: 
Region    Site    RespondentID
Region_1  Site_1  3987227376      1380
                  3980680971       720
          Site_2  3977723249       840
                  3977723089      2160
Name: (Respondent, Duration), dtype: float64
但如果我赋值,然后显示列,则失败:

In [4]: df.loc[:,('Respondent','Duration')] = df.loc[:,'Respondent','Duration')].astype('timedelta64[s]')
       df.loc[:,('Respondent','Duration')]
Out[4]: 
Region    Site    RespondentID
Region_1  Site_1  3987227376     00:00:00.000001
                  3980680971     00:00:00.000000
          Site_2  3977723249     00:00:00.000000
                  3977723089     00:00:00.000002
Name: (Respondent, Duration), dtype: timedelta64[ns]
奇怪的是,如果我这样做:它会起作用:

In [5]: df[('Respondent','Duration')] = df[('Respondent','Duration')].astype('timedelta64[s]')
        df.loc[:,('Respondent','Duration')]
Out[5]:
Region    Site    RespondentID
Region_1  Site_1  3987227376      1380
                  3980680971       720
          Site_2  3977723249       840
                  3977723089      2160
Name: (Respondent, Duration), dtype: float64
另一件奇怪的事情是,如果我过滤一个站点,然后删除该区域,这样我就得到了一个级别索引,它就可以工作了…:

In [6]:
Survey = 'Site_1'
df = df.xs(Survey, level='Site').copy()
​
# Drop the 'Region' from index
df.index = df.index.droplevel(level='Region')

df.loc[:,('Respondent','StartDate')] = pd.to_datetime(df.loc[:,('Respondent','StartDate')])
df.loc[:,('Respondent','EndDate')] = pd.to_datetime(df.loc[:,('Respondent','EndDate')])
df.loc[:,('Respondent','Duration')] = df.loc[:,('Respondent','EndDate')] - df.loc[:,('Respondent','StartDate')]

​# This works fine
df.loc[:,('Respondent','Duration')] = df.loc[:,('Respondent','Duration')].astype('timedelta64[s]')
​
# Display
df.loc[:,('Respondent','Duration')]

Out[6]:
RespondentID
3987227376    1380
3980680971     720
Name: (Respondent, Duration), dtype: float64
很明显,我遗漏了一些关于df.loc[:,tuple]与df[tuple]不同的原因

有人能帮我照一下吗


Python 2.7.9,pandas 0.16.2这是一个bug,我刚刚修复了它,将在0.17.0中出现

要点是这样的。当您执行类似于df.loc[:,column]=value的操作时,它的处理方式与df[[column]]=value完全相同。这意味着类型强制与列的内容无关。将其与df.loc[索引器,列]进行对比,例如,您正在部分设置列。在这里,列的新值和现有数据类型很重要

错误在于,当帧具有多索引时,即使多索引是完整索引,例如,它包含帧中值的完整长度,但它没有采用正确的路径


因此,底线是,这些案例应该也将是相同的。

感谢您的反馈和修复。