2017-11-19 8 views
-1

データフレームで操作をしようとしていますが、私が望むように再フォーマットできないようです。パンダに2Dラベル付き配列を埋め込む

は私が持っている:

>>df = pd.DataFrame({ 
'person':['Al','Al','Bob','Bob','Bob','Sue','Sue'], 
'pet':['Cat','Dog','Fish','Fish','Zebra','Fish','Dog']}) 
>>df 
    person pet 
0  Al Cat 
1  Al Dog 
2 Bob Fish 
3 Bob Fish 
4 Bob Zebra 
5 Sue Fish 
6 Sue Dog 

は、私は一人のレベルに集約したいので、のようなラベルを入れ子にしている:2つのラベル/ pet_info列内の列名がある

person pet_info 
      pet number 
0 Al  Cat 1 
      Dog 1 
1 Bob  Fish 2 
      Zebra 1 
.... 

ようなので、その:

for row in df: 
    print(row['person']) 
    for stuff in row['pet_info']: 
     print(stuff['pet']) 

意志出力:

Al 
Cat 
Dog 
Bob 
Fish 
... 

これはどのように行うのですか?私はこのようにこの変更を実装することはできませんし、私は合理的にパンダに精通しています...

ありがとう!

答えて

0

シンプルgroupby + count/sizeとする必要があります。

df2 = df.groupby(['person', 'pet']).pet.count()\ 
       .to_frame('number').reset_index(level=1) 

df2 

      pet number 
person    
Al  Cat  1 
Al  Dog  1 
Bob  Fish  2 
Bob  Zebra  1 
Sue  Dog  1 
Sue  Fish  1 

df2.columnsMultiIndexを割り当てる:

idx = pd.MultiIndex.from_product([['pet_info'], df2.columns]) 
df2.columns = idx 
df2 = df2.reset_index() 

df2 

    person pet_info  
       pet number 
0  Al  Cat  1 
1  Al  Dog  1 
2 Bob  Fish  2 
3 Bob Zebra  1 
4 Sue  Dog  1 
5 Sue  Fish  1 

さて、あなたはdf2['pet_info']['pet']と、各レベルへのインデックスすることができます。あなたがあなたの質問のように出力したい場合は、逃げることができないgroupby:人によってマルチインデックスう

for n, g in df2.groupby('person'): 
    print(n) 
    for p in g.pet_info.pet: 
     print(p) 

Al 
Cat 
Dog 
Bob 
Fish 
Zebra 
Sue 
Dog 
Fish 
+0

- ペットの組み合わせが、私はのためにのように、異なる方法でデータにアクセスできるようにしたいのです上記で詳しく説明したループ –

+0

@ T.Kevinこのコードを実行し、結果を 'r'に代入し、' r.index.levels [1] 'を実行します。それはあなたの質問に答えますか? –

+0

私はそう信じません。これは、個人とペットの組み合わせでデータフレームをマルチインデックス化します。上記の質問では、行['pet_info']がpet、numberを返すように、サブリストに対してstuff ['pet']がcatを返すように、データを構造化する必要があります。この問題の難しい部分は、集約やグループ化ではなく、forループのような特定の方法でデータにアクセスできることです。助けてくれてありがとう! –