2012-11-26 50 views
35

varsayalım ben yapıyla iç içe bir sözlük 'user_dict' var:Construct pandalar DataFrame

Seviye 1: KullanıcıNo (Uzun Tamsayı)

Seviye 2: Kategori (String)

Seviye 3: Çeşitli özellikler (mantarlar, int, vs ..)

Örneğin

, Bu sözlüğün giriş olacaktır:

user_dict[12] = { 
    "Category 1": {"att_1": 1, 
        "att_2": "whatever"}, 
    "Category 2": {"att_1": 23, 
        "att_2": "another"}} 

"user_dict" her öğe aynı yapıya sahiptir ve "user_dict" dan serisi inşa, bir pandalar DataFrame beslemek istediğiniz öğelerin çok sayıda içerir Öznitellikler. Bu durumda, bir hiyerarşik endeks amaç için yararlı olacaktır.

Özellikle, benim sorum DataFrame yapıcı serisi sözlükte "düzey 3" değerlerinden inşa edilmesi gerektiğini anlamalarına yardımcı olmak için bir yol olup olmadığıdır? Ben endeks olarak kullanıcı kimliklerini sahip (ne elde etmek istediğinizi tersi olan sütun olarak alınır (kullanıcı kimliği yıllardan) "düzey 1" deki

df = pandas.DataFrame(users_summary) 

öğeler:

ben gibi bir şey denerseniz).

Ben sözlüğe giriş yineleme sonra dizi inşa biliyorum, ama daha doğrudan bir yol olup olmadığını bu çok yararlı olacaktır. Benzer bir soru, bir dosyada listelenen json nesnelerine ait bir panda DataFrame oluşturmanın mümkün olup olmadığını sormaktı.

cevap

51

bir MultiIndex dizilerini bir listesini içerir pandas. Bu yüzden en doğal yaklaşım, giriş dict'ınızı yeniden şekillendirmek olacaktır, böylece onun anahtarları, ihtiyaç duyduğunuz çoklu indeks değerlerine karşılık gelen tupllerdir. Sonra sadece seçeneğini orient='index' kullanarak, pd.DataFrame.from_dict kullanarak dataframe hazırlayabilirsiniz:

user_dict = {12: {'Category 1': {'att_1': 1, 'att_2': 'whatever'}, 
        'Category 2': {'att_1': 23, 'att_2': 'another'}}, 
      15: {'Category 1': {'att_1': 10, 'att_2': 'foo'}, 
        'Category 2': {'att_1': 30, 'att_2': 'bar'}}} 

pd.DataFrame.from_dict({(i,j): user_dict[i][j] 
          for i in user_dict.keys() 
          for j in user_dict[i].keys()}, 
         orient='index') 


       att_1  att_2 
12 Category 1  1 whatever 
    Category 2  23 another 
15 Category 1  10  foo 
    Category 2  30  bar 

alternatif bir yaklaşım bileşeni dataframes birleştirerek sizin dataframe kurmak olacaktır: Yani kullanmak için kullanılan

user_ids = [] 
frames = [] 

for user_id, d in user_dict.iteritems(): 
    user_ids.append(user_id) 
    frames.append(pd.DataFrame.from_dict(d, orient='index')) 

pd.concat(frames, keys=user_ids) 

       att_1  att_2 
12 Category 1  1 whatever 
    Category 2  23 another 
15 Category 1  10  foo 
    Category 2  30  bar 
+1

Bu, keyfi derinlikli dağınık listelerle çalışmak için genelleştirmenin makul bir yolu var mı? Örneğin. Bazı dalların diğerlerinden daha kısa olabildiği keyfi bir derinliğe kadar listeler ve daha kısa dallar sona ermediğinde bir Yok veya nan kullanılır? – naught101

+3

Pandalar json desteğine (io tools) ve normalizasyona baktınız mı? http://pandas.pydata.org/pandas-docs/dev/io.html#normalization –

+0

Hayatımı kurtarın !!!!!!!!!! Çok şey öğrenin! teşekkür ederim – Wen

10

sözlükte yinelenen bir döngü için, ama çok daha hızlı çalıştığını bulduğum bir şey bir panele ve daha sonra bir veri alanına dönüştürmektir. Eğer bir sözlük d

import pandas as pd 
d 
{'RAY Index': {datetime.date(2014, 11, 3): {'PX_LAST': 1199.46, 
'PX_OPEN': 1200.14}, 
datetime.date(2014, 11, 4): {'PX_LAST': 1195.323, 'PX_OPEN': 1197.69}, 
datetime.date(2014, 11, 5): {'PX_LAST': 1200.936, 'PX_OPEN': 1195.32}, 
datetime.date(2014, 11, 6): {'PX_LAST': 1206.061, 'PX_OPEN': 1200.62}}, 
'SPX Index': {datetime.date(2014, 11, 3): {'PX_LAST': 2017.81, 
'PX_OPEN': 2018.21}, 
datetime.date(2014, 11, 4): {'PX_LAST': 2012.1, 'PX_OPEN': 2015.81}, 
datetime.date(2014, 11, 5): {'PX_LAST': 2023.57, 'PX_OPEN': 2015.29}, 
datetime.date(2014, 11, 6): {'PX_LAST': 2031.21, 'PX_OPEN': 2023.33}}} 

komutu var ki

pd.Panel(d) 
<class 'pandas.core.panel.Panel'> 
Dimensions: 2 (items) x 2 (major_axis) x 4 (minor_axis) 
Items axis: RAY Index to SPX Index 
Major_axis axis: PX_LAST to PX_OPEN 
Minor_axis axis: 2014-11-03 to 2014-11-06 
pd.Panel (d) [item] Daha sonra komut to_frame vurabilir

pd.Panel(d)['SPX Index'] 
2014-11-03 2014-11-04 2014-11-05 2014-11-06 
PX_LAST 2017.81 2012.10 2023.57 2031.21 
PX_OPEN 2018.21 2015.81 2015.29 2023.33 

bir dataframe verir

() bir veri çerçevesine dönüştürmek için. Büyük ve küçük eksenleri indeks olarak değil, sütunlara dönüştürmek için de reset_index kullanıyorum.siz) (çerçeve Eğer to_frame çağırmadan önce görünümünü değiştirmek için panelin devrik işlevini kullanabilirsiniz görünüşünü beğenmediğiniz

pd.Panel(d).to_frame().reset_index() 
major minor  RAY Index SPX Index 
PX_LAST 2014-11-03 1199.460 2017.81 
PX_LAST 2014-11-04 1195.323 2012.10 
PX_LAST 2014-11-05 1200.936 2023.57 
PX_LAST 2014-11-06 1206.061 2031.21 
PX_OPEN 2014-11-03 1200.140 2018.21 
PX_OPEN 2014-11-04 1197.690 2015.81 
PX_OPEN 2014-11-05 1195.320 2015.29 
PX_OPEN 2014-11-06 1200.620 2023.33 

Son olarak, sadece bir örnek olarak burada dokümantasyon http://pandas.pydata.org/pandas-docs/dev/generated/pandas.Panel.transpose.html

bkz

pd.Panel(d).transpose(2,0,1).to_frame().reset_index() 
major  minor 2014-11-03 2014-11-04 2014-11-05 2014-11-06 
RAY Index PX_LAST 1199.46 1195.323  1200.936 1206.061 
RAY Index PX_OPEN 1200.14 1197.690  1195.320 1200.620 
SPX Index PX_LAST 2017.81 2012.100  2023.570 2031.210 
SPX Index PX_OPEN 2018.21 2015.810  2015.290 2023.330 

Bu yardımcı olur umarım.

+0

Böyle şık bir çözüm! – vk1011

+0

Bunu anlamak daha kolaydı. Teşekkür ederim. – Moondra