2017-03-06 25 views
1

的2级切片一个大熊猫数据帧的位置,我有一个多指标一个熊猫数据框如下:在多指标

>>> import pandas as pd 
>>> category = ['bar', 'bar', 'bar', 'bar', 'bar', 'baz', 'baz', 'baz', 'baz', 
       'baz', 'baz', 'foo', 'foo', 'foo'] 
>>> timestamp = ['2017-01-01 09:00:00', '2017-01-01 09:01:00', '2017-01-01 09:02:00', 
       '2017-01-01 09:03:00', '2017-01-01 09:04:00', '2016-11-18 03:18:00', 
       '2016-11-18 03:19:00', '2016-11-18 03:20:00', '2016-11-18 03:21:00', 
       '2016-11-18 03:22:00', '2016-11-18 03:23:00', '2017-02-03 20:39:00', 
       '2017-02-03 20:40:00', '2017-02-03 20:41:00'] 
>>> values = [1,1,2,2,2,35,3,3,4,4,4,28,28,28] 
>>> tuples = list(zip(*[category,timestamp])) 
>>> index = pd.MultiIndex.from_tuples(tuples, names=['category', 'timestamp']) 
>>> df = pd.DataFrame(values,index=index,columns=['values']) 
>>> df 
            values 
category timestamp     
bar  2017-01-01 09:00:00  1 
     2017-01-01 09:01:00  1 
     2017-01-01 09:02:00  2 
     2017-01-01 09:03:00  2 
     2017-01-01 09:04:00  2 
baz  2016-11-18 03:18:00  35 
     2016-11-18 03:19:00  3 
     2016-11-18 03:20:00  3 
     2016-11-18 03:21:00  4 
     2016-11-18 03:22:00  4 
     2016-11-18 03:23:00  4 
foo  2017-02-03 20:39:00  28 
     2017-02-03 20:40:00  28 
     2017-02-03 20:41:00  28 

对于每个类别,我想找到的次数的次数的累积总和值列的变化,就像这样:

       values changed cum_changes 
category timestamp          
bar  2017-01-01 09:00:00  1 False   0 
     2017-01-01 09:01:00  1 False   0 
     2017-01-01 09:02:00  2 True   1 
     2017-01-01 09:03:00  2 False   1 
     2017-01-01 09:04:00  2 False   1 
baz  2016-11-18 03:18:00  35 False   0 
     2016-11-18 03:19:00  3 True   1 
     2016-11-18 03:20:00  3 False   1 
     2016-11-18 03:21:00  4 True   2 
     2016-11-18 03:22:00  4 False   2 
     2016-11-18 03:23:00  4 False   2 
foo  2017-02-03 20:39:00  28 False   0 
     2017-02-03 20:40:00  28 False   0 
     2017-02-03 20:41:00  28 False   0 

我试着这样做:

df["changes"] = False 
df.iloc[idx[:,1:],1] = df.iloc[idx[:,1:],0] == df.iloc[idx[:,:-1],0] #This doesn't work 
df["cum_changes"] = df["changed"].groupby(level=[0]).cumsum().astype(int) 

但unfortun好吃的第二行不起作用。这与您使用loc进行多值索引的方式类似,但显然,iloc不能以相同的方式处理MultiIndex。我不能按标签进行索引,因为每个组的时间戳是不同的,我不能使用head(),因为每个组的长度都不相同。是否可以在MultiIndex的第二级上进行位置索引?

我实际需要的是“cum_changes”列,“changed”列仅仅是一个中间步骤。如果有另一种计算“cum_changes”列的方法,我很乐意听到它。我知道这可以通过迭代类别列来完成,但似乎应该可以保持向量化,所以我正在寻找一种不涉及循环的解决方案。

我发现此相关的问题,但我不认为它适用,因为该解决方案是不实际的位置索引,而是发现,通过标签对应于给定位置和索引标签: Slice MultiIndex pandas DataFrame by position

+2

使用'DIFF()'函数并检查结果为0,你不需要'iloc'。 – Psidom

回答

1

可以使用diff()作为@Psidom has already said in the comment

In [25]: df['x'] = df.groupby(level=0)['values'] \ 
        .apply(lambda x: x.diff().fillna(0).ne(0).cumsum()) 

In [26]: df 
Out[26]: 
           values x 
category timestamp 
bar  2017-01-01 09:00:00  1 0 
     2017-01-01 09:01:00  1 0 
     2017-01-01 09:02:00  2 1 
     2017-01-01 09:03:00  2 1 
     2017-01-01 09:04:00  2 1 
baz  2016-11-18 03:18:00  35 0 
     2016-11-18 03:19:00  3 1 
     2016-11-18 03:20:00  3 1 
     2016-11-18 03:21:00  4 2 
     2016-11-18 03:22:00  4 2 
     2016-11-18 03:23:00  4 2 
foo  2017-02-03 20:39:00  28 0 
     2017-02-03 20:40:00  28 0 
     2017-02-03 20:41:00  28 0