2016-03-15 21 views
5

Sütun olarak çok indeksli bir DataFrame'im var. Seviye 1'e göre gruplamak ve yeni bir sütun oluşturan bir işlev uygulamak istiyorum. Her bir gruba bu hesaplanan sütunun eklenmesini ve böylece veri grubumun her grup için yeni sütunlara sahip olmasını istiyorum.Gruplandırmayı kullanarak ve her bir gruba sütun eklemek için uygula

Yapmak istediklerimi çoğaltmak için küçük bir komut dosyası ve işlev yaptım. aşağıdaki gibi

import pandas as pd 
import numpy as np 

columns = [('A','julian'),('A','geoffrey'), 
     ('B','julian'),('B','geoffrey'), 
     ('C','julian'),('C','geoffrey')] 

columns = pd.MultiIndex.from_tuples(columns) 

dataframe = pd.DataFrame(data=np.random.rand(10,6),columns=columns) 

def addColumn(inputDF): 
    group = inputDF.columns[0][1] 
    inputDF['sum', group] = inputDF.sum(axis=1) 
    return inputDF 

newColumnsDataframe = dataframe.groupby(level=1, axis=1).apply(addColumn) 

orijinal dataframe şöyledir:

 A     B     C   
    julian geoffrey julian geoffrey julian geoffrey 
0 0.204082 0.073676 0.795725 0.279702 0.258185 0.258112 
1 0.263235 0.096733 0.507324 0.541198 0.525919 0.757652 
2 0.196243 0.028613 0.653408 0.364365 0.174911 0.924733 
3 0.528785 0.831569 0.654160 0.738029 0.940831 0.294473 
4 0.853517 0.263250 0.803087 0.855270 0.701937 0.264698 
5 0.239797 0.069519 0.943544 0.374411 0.189361 0.846647 
6 0.980734 0.290414 0.850097 0.873785 0.903645 0.118713 
7 0.591942 0.088387 0.566298 0.062140 0.568482 0.872064 
8 0.818167 0.061483 0.282050 0.008404 0.449198 0.658370 
9 0.217424 0.427602 0.471933 0.171458 0.390549 0.234426 

aşağıdaki gibi elde edilen dataframe (ayrı ayrı toplam DataFrame inşa bu sonuçları elde etmek için, iki dataframes zincirli) olmalıdır:

 A   B   C  sum   A   B   C \ 
    geoffrey geoffrey geoffrey geoffrey julian julian julian 
0 0.073676 0.279702 0.258112 0.611491 0.204082 0.795725 0.258185 
1 0.096733 0.541198 0.757652 1.395584 0.263235 0.507324 0.525919 
2 0.028613 0.364365 0.924733 1.317710 0.196243 0.653408 0.174911 
3 0.831569 0.738029 0.294473 1.864071 0.528785 0.654160 0.940831 
4 0.263250 0.855270 0.264698 1.383219 0.853517 0.803087 0.701937 
5 0.069519 0.374411 0.846647 1.290578 0.239797 0.943544 0.189361 
6 0.290414 0.873785 0.118713 1.282912 0.980734 0.850097 0.903645 
7 0.088387 0.062140 0.872064 1.022590 0.591942 0.566298 0.568482 
8 0.061483 0.008404 0.658370 0.728257 0.818167 0.282050 0.449198 
9 0.427602 0.171458 0.234426 0.833486 0.217424 0.471933 0.390549 

    sum 
    julian 
0 1.257992 
1 1.296478 
2 1.024561 
3 2.123776 
4 2.358542 
5 1.372703 
6 2.734476 
7 1.726721 
8 1.549415 
9 1.079906 

Yukarıdaki komut dosyasındaki yaklaşım, benim için mantıklı olan ve başkalarının bu tür şeyler yapma konusunda çevrimiçi yazdıkları şeylere dayanmaktadır. Ancak, newColumnsDataframe hala yalnızca 6 sütuna sahiptir, 8 değil (her ad için bir tane eklenmiştir).

Seviye = 0 (A, B veya C) ile gruplandırdığımda ve dönüşümü kullandığımda (ancak bu düzeyde uyguladığımda DEĞİL), newColumnsDataFrame'in 9 sütuna, bir toplam sütunun eklendiğine dikkat ettim her grup için. Aşağıdaki kod bakın:

import pandas as pd 
import numpy as np 

columns = [('A','julian'),('A','geoffrey'), 
     ('B','julian'),('B','geoffrey'), 
     ('C','julian'),('C','geoffrey')] 

columns = pd.MultiIndex.from_tuples(columns) 

dataframe = pd.DataFrame(data=np.random.rand(10,6),columns=columns) 

def addColumn(inputDF): 
    group = inputDF.columns[0][1] 
    inputDF[group, 'sum'] = inputDF.sum(axis=1) 
    return inputDF 

newColumnsDataframe = dataframe.groupby(level=0, axis=1).transform(addColumn) 

O oysa bir bütün dataframe olarak grup ameliyat geçerlidir grup içindeki her sütun üzerinde çalıştı dönüşümü Bildiğim kadarıyla, hep oldu. Bu bununla çelişiyor gibi görünüyor. Ben de düzeyine = 1 grup ve uygulamak yerine dönüşümü kullandığınızda ki fark, aşağıdaki hata atıyor:

ValueError: Length mismatch: Expected axis has 10 elements, new values have 6 elements 

Ben ne olup bittiğini hakkında çok karıştı. Dönüştürme kullandığımda ve level = 0 düzeyinde grup oluşturduğunda bunun neden yapıldığını bilen var mı? Aynı şeyi yaparken neden bir hata var, ancak level = 1'deki grup. Ve neden EITHER seviyesinde gruplandırılmalı ve işlevi UYGULAMA son veri çerçeveme sütun eklemiyor? Şimdiden teşekkürler!

(Not: Bu gerçek DataFrame veya işlev bir sütun eklemek kullanıyorum, sadece daha kolay bir illüstrasyon değildir):

(df.join(pd.concat({'sum': df.groupby(level=1, axis=1).sum()}, axis=1)) 
    .sortlevel(level=1, axis=1)) 

üretir dağınık ait

+1

İstediğiniz bir çıktı ekleyebilir misiniz? – roadrunner66

+0

Yinelenen taşımaktadır. Hedeflediğiniz sonuç nedir? İlginç bir soru, iyi bir yol haritası, ama hedef yok. – Parfait

+0

Sadece orijinal veri çerçevesini ve istenen sonucu ekledim. Umarım bu yardımcı olur! – jjvandermade

cevap

2

Tür, ama bir tek satırlık Benim için bu:

  A   B   C  sum   A   B   C \ 
    geoffrey geoffrey geoffrey geoffrey julian julian julian 
0 0.073676 0.279702 0.258112 0.611490 0.204082 0.795725 0.258185 
1 0.096733 0.541198 0.757652 1.395583 0.263235 0.507324 0.525919 
2 0.028613 0.364365 0.924733 1.317711 0.196243 0.653408 0.174911 
3 0.831569 0.738029 0.294473 1.864071 0.528785 0.654160 0.940831 
4 0.263250 0.855270 0.264698 1.383218 0.853517 0.803087 0.701937 
5 0.069519 0.374411 0.846647 1.290577 0.239797 0.943544 0.189361 
6 0.290414 0.873785 0.118713 1.282912 0.980734 0.850097 0.903645 
7 0.088387 0.062140 0.872064 1.022591 0.591942 0.566298 0.568482 
8 0.061483 0.008404 0.658370 0.728257 0.818167 0.282050 0.449198 
9 0.427602 0.171458 0.234426 0.833486 0.217424 0.471933 0.390549 

     sum 
    julian 
0 1.257992 
1 1.296478 
2 1.024562 
3 2.123776 
4 2.358541 
5 1.372702 
6 2.734476 
7 1.726722 
8 1.549415 
9 1.079906 

burada sadece benim df var" diyen, insanların adlarıyla ilk grubu sağlar ve bunu özetlemek, daha sonra 01 orijinal geri bu iki özetlenebilir sütunları birleştirmek, daha sonra level=1 ve axis=1 sıralamak için sortlevel kullanın. "

C sütunundan sonra görünen 'toplam' tek nedeni, s harfinin C'dan sonra gelmesidir. x adlı bir sütununuz varsa, bu işe yaramaz. Gerçi önemli olsa da emin değilim.

sum_columns = [('sum', name) for name in df.columns.levels[1].tolist()] 
df[sum_columns] = df.groupby(axis=1, level=1).sum() 
df = df.sortlevel(level=1, axis=1) 

sum_columns - Bu [('sum', 'geoffrey'), ('sum', 'julian')] benziyor:

Burada başka bir yaklaşım:

df = pd.DataFrame({ 
     ('C', 'julian'): [0.258185, 0.52591899999999991, 0.17491099999999998, 0.94083099999999997, 0.70193700000000003, 0.189361, 0.90364500000000003, 0.56848199999999993, 0.44919799999999993, 0.39054899999999998], 
     ('B', 'geoffrey'): [0.27970200000000001, 0.54119799999999996, 0.36436499999999999, 0.73802900000000005, 0.85527000000000009, 0.37441099999999999, 0.87378500000000003, 0.062140000000000001, 0.008404, 0.171458], 
     ('A', 'julian'): [0.20408199999999999, 0.263235, 0.196243, 0.52878500000000006, 0.85351699999999997, 0.23979699999999998, 0.98073399999999999, 0.59194199999999997, 0.81816699999999998, 0.21742399999999998], 
     ('B', 'julian'): [0.79572500000000002, 0.507324, 0.65340799999999999, 0.65416000000000007, 0.803087, 0.94354400000000005, 0.85009699999999988, 0.56629799999999997, 0.28205000000000002, 0.47193299999999999], 
     ('A', 'geoffrey'): [0.073676000000000005, 0.096733, 0.028613, 0.831569, 0.26324999999999998, 0.069519000000000011, 0.29041400000000001, 0.088387000000000007, 0.061483000000000003, 0.42760200000000004], 
     ('C', 'geoffrey'): [0.25811200000000001, 0.75765199999999999, 0.92473300000000003, 0.29447299999999998, 0.26469799999999999, 0.84664699999999993, 0.11871300000000001, 0.87206399999999995, 0.65837000000000001, 0.23442600000000002]}, 
     columns=pd.MultiIndex.from_tuples([('A','julian'),('A','geoffrey'), ('B','julian'),('B','geoffrey'), ('C','julian'),('C','geoffrey')])) 

Düzenlendi:

Burada rekreasyon-amaçlarla kullanılan df bu. o adının yanında, sortlevel kullanmak toplamı sütunu olması arzu geçtiyse

df[sum_columns]

düzeyinde 1 her isim için yeni bir 'toplamı' sütun oluşturur.

+0

Bu temiz biriydi! – Zero

+0

Harika! Bunun işe yarayacağını düşünüyorum (Gerçek işlev ve veri çerçevesi daha karmaşıktır, ancak bunun neden aktarılmayacağını anlamıyorlar). Çok teşekkürler. Uygulamanın neden işe yaramadığını biliyor musun? Hala kafamın etrafını sarmak için uğraşıyorum – jjvandermade

+0

Tek düşüncem, fonksiyonunuzda 'group = inputDF.columns [0] [1]' 'julian'' dizgesini döndürüyordu. Birden fazla grupla ('julian', 'geoffrey') bir DataFrameGroupBy nesnesine bir işlev uygulayacağınız için, belki de geoffrey için yapmak için şapka bilmez mi? Bu konuda yanlış olabilirim. 'addColumn (dataframe)' '(sum, julian) sütununu döndürür, ancak bu sütundaki toplamlar, her satır için hem julian hem de geoffrey'in toplamıdır. Sanırım toplamı istediğiniz kişiye göre istediğiniz gibi değiştirmenizi istiyorsunuz. – Jarad

İlgili konular