我在Stata尝试了这个,但失败了。现在尝试Python / pandas - 我不熟悉的东西......
我在考勤数据上有一个数据框,每行都是带时间戳的进入或退出。它看起来像这样:
我想要的是在任何特定时间计算办公室中有多少人。我想设置counter
,为每个条目(type=="O"
)添加1,并为每个退出(type=="C"
)减1。
我的Python尝试是这样的:
df = pd.read_stata("some-data.dta")
sort = df.sort(['date', 'att_time'])
for i, day in enumerate(sort['date']):
sort['counter'][i] = 0
if type=="O":
sort['counter'][i] = sort['counter'][i-1] + 1
elif type=="C":
sort['counter'][i] = sort['counter'][i-1] - 1
这引发了这个错误:
的切片副本上设置值
__main__:2
:SettingWithCopyWarning: 尝试在DataFrame请参阅文档中的警告:http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
通过阅读其他SO帖子,我尝试将复制标记设置为False
(sort.is_copy==False
),但错误消息仍会弹出。另外,令人担忧的是,我注意到它可能没有迭代排序列表:
for i, day in enumerate(sorted(sort['date'])):
print i, day, sort['date'][i]
day
和sort['date'][i]
,应该是相同的日期,不是。因此,即使我绕过i
,我的SettingWithCopyWarning
索引也似乎无法依赖。 HALP?
答案 0 :(得分:3)
您可以使用cumsum
来简化流程,这比手动循环所有行更快。
# artificial data
# =========================
df = pd.DataFrame('0 0 0 0 C 0 C 0 0 C 0 C'.split(), index=pd.date_range('2015-08-31 08:00:00', periods=12, freq='5min'), columns=['type'])
df
type
2015-08-31 08:00:00 0
2015-08-31 08:05:00 0
2015-08-31 08:10:00 0
2015-08-31 08:15:00 0
2015-08-31 08:20:00 C
2015-08-31 08:25:00 0
2015-08-31 08:30:00 C
2015-08-31 08:35:00 0
2015-08-31 08:40:00 0
2015-08-31 08:45:00 C
2015-08-31 08:50:00 0
2015-08-31 08:55:00 C
# processing
# ===================================
df['counter'] = df['type'].map({'0': 1, 'C': -1}).cumsum()
df
type counter
2015-08-31 08:00:00 0 1
2015-08-31 08:05:00 0 2
2015-08-31 08:10:00 0 3
2015-08-31 08:15:00 0 4
2015-08-31 08:20:00 C 3
2015-08-31 08:25:00 0 4
2015-08-31 08:30:00 C 3
2015-08-31 08:35:00 0 4
2015-08-31 08:40:00 0 5
2015-08-31 08:45:00 C 4
2015-08-31 08:50:00 0 5
2015-08-31 08:55:00 C 4