12

我有一个 DataFrame df,我已经对其进行了“分组”。我正在寻找一个类似于 get_group(name) 的函数,除了如果名称不存在而不是抛出 KeyError ,而是返回一个空的 DataFrame (或其他值),类似于 dict.get 的工作方式:

g = df.groupby('x')

# doesn't work, but would be nice:
i = g.get_group(1, default=[])

# does work, but is hard to read:
i = g.obj.take(g.indices.get(1, []), g.axis)

是否已经有提供此功能的功能?

编辑:

在许多方面,GroupBy 对象由字典(.indicies、.groups)表示,这种“默认获取”功能对于字典的概念来说已经足够核心,它包含在 Python 语言本身中。似乎如果类似dict的东西没有默认设置,也许我没有正确理解它?为什么像 dict 这样的东西没有“默认获取”?

我想做的一个简短的例子是:

df1_bymid = df1.groupby('mid')
df2_bymid = df2.groupby('mid')

for mid in set(df1_bymid.groups) | set(df2_bymid.groups) :
    rows1 = df1_bymid.get_group(mid, [])
    rows2 = df1_bymid.get_group(mid, [])
    for row1, row2 in itertools.product(rows1, rows2) :
        yield row1, row2

当然,我可以创建一个函数,而且我可能会,似乎如果我不得不走这么远,也许我没有按照预期的方式使用 GroupBy 对象:

def get_group(df, name, obj=None, default=None) :
    if obj is None :
        obj = df.obj

    try :
        inds = df.indices[name]
    except KeyError, e :
        if default is None :
            raise e

        inds = default

    return df.obj.take(inds, df.axis)
4

3 回答 3

7

我可能会定义我自己get_group()的如下

In [55]: def get_group(g, key):
   ....:     if key in g.groups: return g.get_group(key)
   ....:     return pd.DataFrame()
   ....: 

In [52]: get_group(g, 's1')
Out[52]: 
   Mt Sp  Value  count
0  s1  a      1      3
1  s1  b      2      2

In [54]: get_group(g, 's4')
Out[54]: 
Empty DataFrame
Columns: []
Index: []   
于 2013-11-06T18:15:54.117 回答
2

它不是那么漂亮,但你可以这样做:

设置:

>>> df = pandas.DataFrame([[1,2,3],[4,5,6],[1,8,9]], columns=['a','b','c'])
>>> df
   a  b  c
0  1  2  3
1  4  5  6
2  1  8  9
>>> g = df.groupby('a')

现在g.get_group要求传递的密钥存在于底层groups字典中,但您可以自己访问该成员,实际上它是一个普通的 python dict。它将组值带入索引集合:

>>> g.groups
{1: Int64Index([0, 2], dtype='int64'), 4: Int64Index([1], dtype='int64')}
>>> type(g.groups)
<type 'dict'>

如果您在数据帧的索引位置函数中使用这些返回的索引,您可以像以下方式一样获取您的组get_group

>>> df.loc[g.groups[1]]
   a  b  c
0  1  2  3
2  1  8  9

既然groupsdict你可以使用的get方法。如果不提供默认值,这将返回None,这将导致loc引发异常。但它会接受一个空列表:

>>> df.loc[g.groups.get(1, [])]
   a  b  c
0  1  2  3
2  1  8  9
>>> df.loc[g.groups.get(2, [])]
Empty DataFrame
Columns: [a, b, c]
Index: []

它不像提供默认值那样干净get_group(也许他们应该在未来的版本中添加该功能),但它可以工作。

于 2017-02-24T14:24:44.137 回答
0

您可以使用 adefaultdict来实现这一点。

假设您有一个 groupby 对象,该对象将大于零的列上的数据拆分。问题是所有值都可能大于或小于零,这意味着您无法确定 groupby 中是否有 1 个或 2 个数据帧可用。

g_df = df.groupby(df.some_column.gt(0))  

然后有2种方法

df_dict  = defaultdict(pd.DataFrame, {i:i_df for i,i_df in g_df} )
df_dict[True]
df_dict[False]                                                                                                                                                                                                         

或者:

df_dict  = defaultdict(list, g_df.groups)                                                                                                                                                                                                                                      
df.loc[df_dict[True]]
df.loc[df_dict[False]]

我没有测试哪个更有效,显然第二种方法只在索引而不是数据帧上创建一个 defaultdict - 所以很可能更有效。

于 2019-06-22T01:51:48.533 回答