我有一点奇怪的情况,我不明白为什么它在一种情况下起作用而不是另一种情况。
我正在尝试在timedelta64 [ns]到timedelta64 [s]的多索引上投射一列,而且我还有一行的多索引。 如果元组是我想要的列(level_0,level_1):
适用于df [tuple] = df [tuple] .astype(timedelta64 [s])
它不适用于df.loc [:,tuple] .astype(timedelta64 [s])
以下是一些示例数据(csv):
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]:
我想创建一个列“持续时间”(然后一个名为“DurationMinutes”,将持续时间除以60)。
我首先将日期转换为日期时间:
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
另一件奇怪的事情,如果我过滤一个网站,并删除Region以便我最终得到一个单级索引,它就可以......:
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
答案 0 :(得分:4)
这是一个错误,我刚修好它here,将在0.17.0。
要点就是这个。当您执行df.loc[:,column] = value
之类的操作时,此操作与df[[column]] = value
完全相同。这意味着类型强制与列WAS无关。将其与df.loc[indexer,column]
对比,例如您正在部分设置列。这里新值和列的现有dtype很重要。
错误是当帧具有多索引时,即使多索引是完整索引(例如,它包含帧中的全部值),它也没有采用正确的路径。
所以底线是这些案例应该(并且将会)相同。