pandas中的groupby()和索引值

时间:2018-01-28 17:10:55

标签: python pandas

我有pandas.DataFrame Multiindex,因此:

a         val
   dog    1
   cat    2
b         
   fox    3
   rat    4

我想要一个系列,其条目是级别1的索引值列表,

这样:

a    [dog, cat]
b    [fox, rat]

以下确实有效,但是非常缓慢且不优雅:

fff = df.groupby(level=0)['val'].agg(lambda x:[i[1] for i in list(x.index.values)])

所以我希望有更好的方法。

2 个答案:

答案 0 :(得分:2)

reset_indexgroupby

df.reset_index(level=1).groupby(level=0)['level_1'].apply(list)


Out[21]: 
a    [dog, cat]
b    [fox, rat]
Name: level_1, dtype: object

答案 1 :(得分:1)

为了获得超过Wen's Answer的另一个数量级,我们可以使用原生迭代器,如:

代码:

index_as_dict = {}
for k, v in index.ravel():
    index_as_dict.setdefault(k, []).append(v)
pd.Series(index_as_dict)

测试代码:

import pandas as pd

df = pd.read_fwf(StringIO(u"""
    level_0  level_1     val
    a        dog         1
    a        cat         2
    b        fox         3
    b        rat         4"""), header=1).set_index(['level_0', 'level_1'])
print(df)

def method1():
    return df.reset_index(level=1).groupby(level=0)['level_1'].apply(list)

def method2():
    index_as_dict = {}
    for k, v in df.index.ravel():
        index_as_dict.setdefault(k, []).append(v)
    return pd.Series(index_as_dict)

print(method1())
print(method2())

from timeit import timeit
print(timeit(method1, number=50))
print(timeit(method2, number=50))

结果:

                 val
level_0 level_1     
a       dog        1
        cat        2
b       fox        3
        rat        4
level_0
a    [dog, cat]
b    [fox, rat]
Name: level_1, dtype: object
a    [dog, cat]
b    [fox, rat]
dtype: object

0.0760027870983045
0.006749932432252637