2013-11-29 16 views
5

varsayalım bir dataframe şöyle var tanımlamak için uygula vs:Python Pandalar: Agrega kullanma yeni sütunlar

n = 20 
dim1 = np.random.randint(1, 3, size=n) 
dim2 = np.random.randint(3, 5, size=n) 
data1 = np.random.randint(10, 20, size=n) 
data2 = np.random.randint(1, 10, size=n) 
df = pd.DataFrame({'a': dim1, 'b': dim2 ,'val1': data1, 'val2': data2}) 

Ben grup akıllıca döndüren bir işlev tanımlarsanız: teker

def h(x): 
    if x['val2'].sum() == 0: 
     return 0 
    else: 
     return (x['val1'].sum())*1.0/x['val2'].sum()*1.0 

Gruplamasını sütunların ve döndürür bir sonuç toplayarak:

df.groupby(['a']).aggregate(h)['val1'] 

o d mevcut tüm sütunları dönüştürür Gerçi iki sütun tarafından yeni bir sütun

Gruplama eklemek yerine sonuç esired agrega kullanırken bir hata ile sonuçlanır:

df.groupby(['a','b']).aggregate(h)['val1'] 

KeyError: 'val2' 

Ama iş gibi görünüyor uygulamak için agrega anahtarlama.

  1. Neden çalışmalarını uygulamak ve aggregte değildir:

    iki soru var?

  2. Bir veri kümesini bir grup anahtarla grupladıktan sonra, grup değerlerini yeni bir sütun olarak birleştiren bir işlev kullanmak isterim, bunu yapmanın en iyi yolu nedir?

Şimdiden teşekkürler.

+0

İyi sorum var.Aslında, def testi (x) gibi bir test fonksiyonunu tanımlarsanız: print x; x.sum() 'i döndürün ve her iki durumda da 'topla' komutunu çağırın, ilk durumda' x 'ın bir DataFrame olduğunu ve ikinci durumda 'x''in bir Series olduğunu görürsünüz. her zaman DataFrame). Şu anda kodun içine girmek için zamanım yok, ve eminim ki bazı pandalar geliştiriciler bu davranışı ortaya çıkaracak ve açıklayacaktır :) –

+0

2'de sorduğunuzdan emin değilsiniz (belki de [cumcount] (http://pandas.pydata.org/pandas-docs/dev/groupby.html#enumerate-group-items)?) –

+0

Bu grup çalışmasıyla tam olarak neler olup bittiğini öğrenmek için uğraştım. Romanın belirttiği gibi, agg'e geçen ilk argüman bir dizidir, bu nedenle birden çok sütundaki değerlere göre aggre etmek istiyorsanız, otomatik olarak iletilen dizinin indeks değerlerine dayanarak işlevdeki ikinci sütunu çağırmanız gerekir. Uygula, her zaman işaret ettiği gibi veri çerçevesi olarak geçer. Bazı gerçekten garip davranışları görmek için dönüşüm kontrolünü görmek istiyorsanız, diziye ve dataframe fonksiyonun ilk argümanı olarak geçiyor gibi görünüyor. Oldukça kafa karıştırıcı IMO –

cevap

0

Biraz geri adım atmak için, bu özel "toplama" işleminin daha hızlı bir yolu sum (it's optimised in cython)'u birkaç kez kullanmaktır.

In [11]: %timeit g.apply(h) 
1000 loops, best of 3: 1.79 ms per loop 

In [12]: %timeit g['val1'].sum()/g['val2'].sum() 
1000 loops, best of 3: 600 µs per loop 

IMO GroupBy kodu oldukça kıllı ve genellikle tembel "kara kutu" olarak hangi değerleri listesini oluşturarak, neler olup bittiğini de gözetleme görüyor:

def h1(x): 
    a.append(x) 
    return h(x) 
a = [] 

Uyarı: bazen tipi Bu listede yer alan veriler tutarlı değildir (pandalar, herhangi bir hesaplama yapmadan önce birkaç farklı şeyi dener).

ikinci toplanma her sütun uygulanması takılıp, bu nedenle (bir hata yükseltir) grubu olur:

0  10 
4  16 
8  13 
9  17 
17 17 
19 11 
Name: val1, dtype: int64 

Bu VAL1 kolonu (a, b) = arasında seriye, makine türüne (olup 1, 3). Bu belki de başka bir şey denemek olabilir yükseltir sonra

Bu de bir hata olabilir ... ilgilenenler için

(benim şüphe bu ilkler versiyonu neden çalıştığını, bu kadar kasalı özel olan olmasıdır) Ben olsun a geçerli:

In [21]: a 
Out[21]: 
[SNDArray([125755456, 131767536,  13,  17,  17,  11]), 
Series([], name: val1, dtype: int64), 
0  10 
4  16 
8  13 
9  17 
17 17 
19 11 
Name: val1, dtype: int64] 

Ben SNDArray ne hakkında olduğunu hiçbir fikri ...

+0

SNDArray, bir ad özelliğine sahip (örneğin, 0.13 Serisi gibi) bir numpy dizi alt sınıfıdır. Cython bir dizi yerine bir dizi yerine bir dizi daha çok daha hızlı bir şekilde bir – Jeff

+0

@Andy Hayden inşa etmek için daha iyi bir yaklaşım gibi görünüyor, ancak en iyi yaklaşım gibi, agrega() başarısız olduğunda cythonized işlevleri kullanmak veya uygulamak için kullanmak gibi geliyor? Ayrıca, groupby kodunun 'tüylü' olmasının onun güvenilir olmadığını düşündüğün anlamına gelmediğini hayal ediyorum. SQL'de aldığım sonuçları tutarlı bir şekilde eşleştiriyor gibi görünüyor. Teşekkürler. – AllenQ

+0

Güvenilmez, sadece bir çok şey var. –

İlgili konular