Pandas:迭代df中的已排序行,实现计数器

时间:2015-08-31 18:11:08

标签: python pandas

我在Stata尝试了这个,但失败了。现在尝试Python / pandas - 我不熟悉的东西......

我在考勤数据上有一个数据框,每行都是带时间戳的进入或退出。它看起来像这样: baseline data

我想要的是在任何特定时间计算办公室中有多少人。我想设置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帖子,我尝试将复制标记设置为Falsesort.is_copy==False),但错误消息仍会弹出。另外,令人担忧的是,我注意到它可能没有迭代排序列表:

                for i, day in enumerate(sorted(sort['date'])):
                    print i, day, sort['date'][i]

daysort['date'][i],应该是相同的日期,不是。因此,即使我绕过i,我的SettingWithCopyWarning索引也似乎无法依赖。 HALP?

1 个答案:

答案 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