2017-11-22 18 views
4

部分行のリストを取得する方法を探していました。パンダを使用してデータフレームから同じ名前の行のリストを取得

Name x y r 
    a  9 81 63 
    a  98 5 89 
    b  51 50 73 
    b  41 22 14 
    c  6 18 1 
    c  1 93 55 
    d  57 2 90 
    d  58 24 20 

ので、私は次のように辞書を取得しようとしていた、

di = {a:{0: [9,81,63], 1: [98,5,89]}, 
    b:{0:[51,50,73], 1:[41,22,14]}, 
    c:{0:[6,18,1], 1:[1,93,55]}, 
    d:{0:[57,2,90], 1:[58,24,20]}} 
+0

を使用
は、だからあなたの質問と何をしようとしたのは何ですか? – marcolz

+0

「di」と正確な出力を得たいと思っていました。私が試みたのは、データフレーム全体をdictとして取得し、次にdictをループして出力と同じ新しいdictを作成することです。しかし、それはあまりにも複雑なようだと私はパンダと簡単に行うために何かを欠いていると確信しています! – user2995912

答えて

4

使用groupbycountlist秒、最後の変換出力Seriesto_dictのカスタム機能付:

di = (df.groupby('Name')['x','y','r'] 
     .apply(lambda x: dict(zip(range(len(x)),x.values.tolist()))) 
     .to_dict()) 

print (di) 
{'b': {0: [51, 50, 73], 1: [41, 22, 14]}, 
'a': {0: [9, 81, 63], 1: [98, 5, 89]}, 
'c': {0: [6, 18, 1], 1: [1, 93, 55]}, 
'd': {0: [57, 2, 90], 1: [58, 24, 20]}} 

詳細:

print (df.groupby('Name')['x','y','r'] 
     .apply(lambda x: dict(zip(range(len(x)),x.values.tolist())))) 
Name 
a  {0: [9, 81, 63], 1: [98, 5, 89]} 
b {0: [51, 50, 73], 1: [41, 22, 14]} 
c  {0: [6, 18, 1], 1: [1, 93, 55]} 
d  {0: [57, 2, 90], 1: [58, 24, 20]} 
dtype: object 

が提案使用enumerateためにあなたvolcanoありがとう:

di = (df.groupby('Name')['x','y','r'] 
     .apply(lambda x: dict(enumerate(x.values.tolist()))) 
     .to_dict()) 

をより良いテストのための可能な使用のカスタム関数です:

def f(x): 
    #print (x) 
    a = range(len(x)) 
    b = x.values.tolist() 
    print (a) 
    print (b) 
    return dict(zip(a,b)) 

[[9, 81, 63], [98, 5, 89]] 
range(0, 2) 
[[9, 81, 63], [98, 5, 89]] 
range(0, 2) 
[[51, 50, 73], [41, 22, 14]] 
range(0, 2) 
[[6, 18, 1], [1, 93, 55]] 
range(0, 2) 
[[57, 2, 90], [58, 24, 20]] 

di = df.groupby('Name')['x','y','r'].apply(f).to_dict() 
print (di) 
+0

ありがとうございます。完璧に走ります!私がそれをはっきり理解する時間です。 – user2995912

+0

あなたはようこそ!私は、より良いデバッグのためにカスタム関数でソリューションを追加します。 – jezrael

+1

_zip_-pingの代わりに_enumerate_を_range_と使用することをお勧めします – volcano

5

時にはそれは、フットプリントとオーバーヘッドを最小化するのが最善です。 itertools.countcollections.defaultdict

from itertools import count 
from collections import defaultdict 

counts = {k: count(0) for k in df.Name.unique()} 
d = defaultdict(dict) 

for k, *v in df.values.tolist(): 
    d[k][next(counts[k])] = v 

dict(d) 

{'a': {0: [9, 81, 63], 1: [98, 5, 89]}, 
'b': {0: [51, 50, 73], 1: [41, 22, 14]}, 
'c': {0: [6, 18, 1], 1: [1, 93, 55]}, 
'd': {0: [57, 2, 90], 1: [58, 24, 20]}} 
+0

SIRはsetdefaultで同じことができるかどうか疑問に思っていますか?私は試しましたが、それを正しく得ることができませんでした – Dark

+0

はい、私はちょうど与えた答えを探していた...しかし、私はそれを見つけることができません。 – piRSquared

関連する問題