Python Pandas:如果groupby中任何前一行中的值满足某个条件,则从数据帧中消除一行

时间:2014-11-13 14:40:35

标签: python pandas row slice

我试图在周变为非顺序超过1时从组中删除数据。即如果一周内有间隙,那么我想删除该组中的那一行和后续行。下面是我所拥有的数据结构的一个简单例子,也是我正在寻找的理想输出。数据需要按国家/地区和产品分组。

import pandas as pd

data = {'Country' : ['US','US','US','US','US','DE','DE','DE','DE','DE'],'Product' :         ['Coke','Coke','Coke','Coke','Coke','Apple','Apple','Apple','Apple','Apple'],'Week' : [1,2,3,4,6,1,2,3,5,6] }

df = pd.DataFrame(data)

print df

#Current starting Dataframe.
  Country Product  Week
0      US    Coke     1
1      US    Coke     2
2      US    Coke     3
3      US    Coke     4
4      US    Coke     6
5      DE   Apple     1
6      DE   Apple     2
7      DE   Apple     3
8      DE   Apple     5
9      DE   Apple     6

#Ideal Output below:
  Country Product  Week
0      US    Coke     1
1      US    Coke     2
2      US    Coke     3
3      US    Coke     4
5      DE   Apple     1
6      DE   Apple     2
7      DE   Apple     3

因此输出会删除美国可口可乐的第6周,因为前一周是4。 对于DE Apple Week 5& 6被删除,因为前一周到第5周是3.注意这也消除了DE Apple Week 6,即使它的前面是5或者diff()为1。

2 个答案:

答案 0 :(得分:1)

这应该有效

df.groupby(['Country', 'Product']).apply(lambda sdf: sdf[(sdf.Week.diff(1).fillna(1) != 1).astype('int').cumsum() == 0]).reset_index(drop=True)

另一种可能更具可读性的方法(即生成一组连续的周并检查观察到的一周)

df['expected_week'] = df.groupby(['Country', 'Product']).Week.transform(lambda s: range(s.min(), s.min() + s.size))
df[df.Week == df.expected_week]

答案 1 :(得分:1)

你可以尝试这种方法......

def eliminate(x):
    x['g'] = x['Week'] - np.arange(x.shape[0])
    x = x[x['g'] == x['g'].min()]
    x = x.drop('g',1)

    return x

out  = df.groupby('Product').apply(eliminate).reset_index(level=0,drop=True)