2014-03-06 216 views
67

我有一個像熊貓的數據幀:在大熊貓列表分組行GROUPBY

A 1 
A 2 
B 5 
B 5 
B 4 
C 6 

我想小組第一列,並得到行第二列的列表:

A [1,2] 
B [5,5,4] 
C [6] 

是有可能使用pandas groupby做這樣的事情嗎?

+1

在數據框中存儲列表效率低下,你爲什麼要這樣做的任何原因? – EdChum

+1

列表是一個例子,可以是任何東西,我可以訪問所有條目從同一組中 –

+0

一排,我認爲如果你只是被列分組並訪問與該組則省去了生成一個列表中的數據,有什麼將被返回的是該組的熊貓數據框/系列 – EdChum

回答

106

你可以做到這一點使用groupby到組感興趣的列,然後applylist到每個組:

In [1]: 
# create the dataframe  
df = pd.DataFrame({'a':['A','A','B','B','B','C'], 'b':[1,2,5,5,4,6]}) 
df 
Out[1]: 
    a b 
0 A 1 
1 A 2 
2 B 5 
3 B 5 
4 B 4 
5 C 6 

[6 rows x 2 columns] 

In [76]: 
df.groupby('a')['b'].apply(list) 

Out[76]: 
a 
A  [1, 2] 
B [5, 5, 4] 
C   [6] 
Name: b, dtype: object 
+3

如果數據集非常龐大,說1000萬行,這將花費大量的時間。有沒有更快的方法來做到這一點?然而,'a'中的唯一身份數量大約爲500k –

+3

groupby出了名的緩慢和內存飢餓,你可以做的是按列A排序,然後找到idxmin和idxmax(可能將其存儲在一個字典中)並使用它來切片你的數據框會更快,我認爲 – EdChum

+0

@AbhishekThakur實際上是行不通的'idxmin'不會爲字符串的工作,你需要存儲的開始和結束的索引值 – EdChum

7

正如你說一個pd.DataFrame對象可以做的工作的groupby方法。

L = ['A','A','B','B','B','C'] 
N = [1,2,5,5,4,6] 

import pandas as pd 
df = pd.DataFrame(zip(L,N),columns = list('LN')) 


groups = df.groupby(df.L) 

groups.groups 
     {'A': [0, 1], 'B': [2, 3, 4], 'C': [5]} 

賦予和基團的指數明智描述。

要獲得單組的元素,你可以做,例如

groups.get_group('A') 

    L N 
    0 A 1 
    1 A 2 

    groups.get_group('B') 

    L N 
    2 B 5 
    3 B 5 
    4 B 4 
13

如果性能很重要,請下至numpy級別:

import numpy as np 

df = pd.DataFrame({'a':np.random.randint(0,60,600), 'b':[1,2,5,5,4,6]*100}) 

def f(df): 
     keys,values=df.sort_values('a').values.T 
     ukeys,index=np.unique(keys,True) 
     arrays=np.split(values,index[1:]) 
     df2=pd.DataFrame({'a':ukeys,'b':[list(a) for a in arrays]}) 
     return df2 

測試:

In [301]: %timeit f(df) 
1000 loops, best of 3: 1.64 ms per loop 

In [302]: %timeit df.groupby('a')['b'].apply(list) 
100 loops, best of 3: 5.26 ms per loop