2015-07-05 20 views
7

ilk satırı silin ben şöyle Aşağıdaki büyük dataframe (df):Python: Pandalar - grubun

ID  date  PRICE  
1 10001 19920103 14.500  
2 10001 19920106 14.500  
3 10001 19920107 14.500  
4 10002 19920108 15.125  
5 10002 19920109 14.500 
6 10002 19920110 14.500  
7 10003 19920113 14.500 
8 10003 19920114 14.500  
9 10003 19920115 15.000 

Soru: silmek (veya kaldırmak) için en etkili yol nedir Her kimliğin ilk satırı?

 ID  date  PRICE  
    2 10001 19920106 14.500  
    3 10001 19920107 14.500  
    5 10002 19920109 14.500 
    6 10002 19920110 14.500  
    8 10003 19920114 14.500  
    9 10003 19920115 15.000 

ben her benzersiz ID üzerinde bir döngü yapmak ve ilk satırı kaldırabilirsiniz ama bu çok etkili olmadığına inanıyorum: Bunu istiyorum.

cevap

10

İstediğiniz satırlar için Doğru olan ve istemediğiniz satırlar için False olan bir boole maskesi hazırlamak için groupby/transform kullanabilirsiniz. Eğer böyle bir boole maskesi sahip olduktan sonra, df.loc[mask] kullanarak alt DataFrame seçebilirsiniz:

import numpy as np 
import pandas as pd 

df = pd.DataFrame(
    {'ID': [10001, 10001, 10001, 10002, 10002, 10002, 10003, 10003, 10003], 
    'PRICE': [14.5, 14.5, 14.5, 15.125, 14.5, 14.5, 14.5, 14.5, 15.0], 
    'date': [19920103, 19920106, 19920107, 19920108, 19920109, 19920110, 
       19920113, 19920114, 19920115]}, 
    index = range(1,10)) 

def mask_first(x): 
    result = np.ones_like(x) 
    result[0] = 0 
    return result 

mask = df.groupby(['ID'])['ID'].transform(mask_first).astype(bool) 
print(df.loc[mask]) 

 ID PRICE  date 
2 10001 14.5 19920106 
3 10001 14.5 19920107 
5 10002 14.5 19920109 
6 10002 14.5 19920110 
8 10003 14.5 19920114 
9 10003 15.0 19920115 
Eğer verimlilik ilgilendiğiniz yana

verir, burada bir kriter:

import timeit 
import operator 
import numpy as np 
import pandas as pd 

N = 10000 
df = pd.DataFrame(
    {'ID': np.random.randint(100, size=(N,)), 
    'PRICE': np.random.random(N), 
    'date': np.random.random(N)}) 

def using_mask(df): 
    def mask_first(x): 
     result = np.ones_like(x) 
     result[0] = 0 
     return result 

    mask = df.groupby(['ID'])['ID'].transform(mask_first).astype(bool) 
    return df.loc[mask] 

def using_apply(df): 
    return df.groupby('ID').apply(lambda group: group.iloc[1:, 1:]) 

def using_apply_alt(df): 
    return df.groupby('ID', group_keys=False).apply(lambda x: x[1:]) 

timing = dict() 
for func in (using_mask, using_apply, using_apply_alt): 
    timing[func] = timeit.timeit(
     '{}(df)'.format(func.__name__), 
     'from __main__ import df, {}'.format(func.__name__), number=100) 

for func, t in sorted(timing.items(), key=operator.itemgetter(1)): 
    print('{:16}: {:.2f}'.format(func.__name__, t)) 

bildiriyor
using_mask  : 0.85 
using_apply_alt : 2.04 
using_apply  : 3.70 
+0

olduğunu! teşekkür ederim – Plug4

8

Başka bir satır kod vay etkileyici df.groupby('ID').apply(lambda group: group.iloc[1:, 1:])

Out[100]: 
      date PRICE 
ID      
10001 2 19920106 14.5 
     3 19920107 14.5 
10002 5 19920109 14.5 
     6 19920110 14.5 
10003 8 19920114 14.5 
     9 19920115 15.0 
+0

İlk cevaptan bin kat daha basit! Ben sana teşekkür ederim –