Удалить последнюю строку в группе, основываясь на условии - PullRequest
1 голос
/ 27 октября 2019

Я хочу удалить последнюю строку в группе на основе условия. Я сделал следующее:

df=pd.read_csv('file')
grp = df.groupby('id')
for idx, i in grp:
   df= df[df['column2'].index[-1] == 'In']

     id     product   date
 0   220    in      2014-09-01 
 1   220    out     2014-09-03 
 2   220    in      2014-10-16
 3   826    in     2014-11-11
 4   826    out     2014-12-09
 5   826    out      2014-05-19
 6   901    in      2014-09-01
 7   901    out     2014-10-05
 8   901    out     2014-11-01

Когда я делаю это, я просто получаю: KeyError: False

мой желаемый результат будет:

     id     product   date
 0   220    in      2014-09-01 
 1   220    out     2014-09-03
 3   826    in     2014-11-11
 4   826    out     2014-12-09 
 6   901    in      2014-09-01
 7   901    out     2014-10-05

Ответы [ 2 ]

1 голос
/ 27 октября 2019

Простой способ - добавить skipfooter=1 при открытии CSV-файла:

df = pd.read_csv(file, skipfooter=1, engine='python')
1 голос
/ 27 октября 2019

Если хотите удалить последнюю in только для групп, инвертируйте маску цепи с Series.duplicated на ~ с не равным in с Series.ne:

df = df[~df['id'].duplicated() | df['product'].ne('in')]
print (df)
    id product        date
0  220      in  2014-09-01
1  220     out  2014-09-03
3  826      in  2014-11-11
4  826     out  2014-12-09
5  826     out  2014-05-19
6  901      in  2014-09-01
7  901     out  2014-10-05
8  901     out  2014-11-01

РЕДАКТИРОВАТЬ:

Если хотите, чтобы все возможные пары in-out для групп использовали это решение , только необходимые сопоставления не числовые значения in-out с числовыми с dict,потому что rolling не работает со строками:

#more general solution
print (df)
     id product        date
0   220     out  2014-09-03
1   220     out  2014-09-03
2   220      in  2014-09-01
3   220     out  2014-09-03
4   220      in  2014-10-16
5   826      in  2014-11-11
6   826      in  2014-11-11
7   826     out  2014-12-09
8   826     out  2014-05-19
9   901      in  2014-09-01
10  901     out  2014-10-05
11  901      in  2014-09-01
12  901     out  2014-11-01

pat = np.asarray(['in','out'])
N = len(pat)

d = {'in':0, 'out':1}
ma  = (df['product'].map(d)
                   .groupby(df['id'])
                   .rolling(window=N , min_periods=N)
                   .apply(lambda x: (x==list(d.values())).all(), raw=False)
                   .mask(lambda x: x == 0) 
                   .bfill(limit=N-1)
                   .fillna(0)
                   .astype(bool)
                   .reset_index(level=0, drop=True)
             )
df = df[ma]
print (df)
     id product        date
2   220      in  2014-09-01
3   220     out  2014-09-03
6   826      in  2014-11-11
7   826     out  2014-12-09
9   901      in  2014-09-01
10  901     out  2014-10-05
11  901      in  2014-09-01
12  901     out  2014-11-01
...