Как получить доступ к pandas groupby dataframe по ключу
Как мне получить доступ к соответствующей группе по кадру данных в объекте groupby с помощью ключа? С помощью следующей группы:
rand = np.random.RandomState(1)
df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
'B': rand.randn(6),
'C': rand.randint(0, 20, 6)})
gb = df.groupby(['A'])
Я могу прокручивать его, чтобы получить ключи и группы:
In [11]: for k, gp in gb:
print 'key=' + str(k)
print gp
key=bar
A B C
1 bar -0.611756 18
3 bar -1.072969 10
5 bar -2.301539 18
key=foo
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
Я хотел бы иметь возможность сделать что-то вроде
In [12]: gb['foo']
Out[12]:
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
Но когда я это делаю (ну, на самом деле, мне нужно делать gb[('foo',)]
), я получаю эту странную вещь pandas.core.groupby.DataFrameGroupBy
, которая, похоже, не имеет методов, соответствующих DataFrame, которые я хочу.
Лучшее, что я могу придумать, -
In [13]: def gb_df_key(gb, key, orig_df):
ix = gb.indices[key]
return orig_df.ix[ix]
gb_df_key(gb, 'foo', df)
Out[13]:
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
но это отвратительно, учитывая, насколько хорош pandas в этих вещах.
Каким образом это сделать?
Ответы
Ответ 1
Вы можете использовать метод get_group
:
In [21]: gb.get_group('foo')
Out[21]:
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
Примечание. Это не требует создания промежуточного словаря/копии каждого поддиафрагмента для каждой группы, поэтому будет гораздо более эффективно с точки зрения памяти, создающей наивный словарь с dict(iter(gb))
. Это связано с тем, что он использует структуры данных, уже доступные в объекте groupby.
Вы можете выбрать разные столбцы с помощью группировки по секциям:
In [22]: gb[["A", "B"]].get_group("foo")
Out[22]:
A B
0 foo 1.624345
2 foo -0.528172
4 foo 0.865408
In [23]: gb["C"].get_group("foo")
Out[23]:
0 5
2 11
4 14
Name: C, dtype: int64
Ответ 2
Wes McKinney (pandas 'author) в Python для анализа данных предлагает следующий рецепт:
groups = dict(list(gb))
который возвращает словарь, ключи которого являются вашими метками группы и значениями которых являются DataFrames, т.е.
groups['foo']
даст то, что вы ищете:
A B C
0 foo 1.624345 5
2 foo -0.528172 11
4 foo 0.865408 14
Ответ 3
Вместо
gb.get_group('foo')
Я предпочитаю использовать gb.groups
df.loc[gb.groups['foo']]
Потому что таким образом вы можете выбрать несколько столбцов. например:
df.loc[gb.groups['foo'],('A','B')]
Ответ 4
gb = df.groupby(['A'])
gb_groups = grouped_df.groups
Если вы ищете выборочные объекты groupby, выполните следующие действия: gb_groups.keys() и введите желаемый ключ в следующий key_list.
gb_groups.keys()
key_list = [key1, key2, key3 and so on...]
for key, values in gb_groups.iteritems():
if key in key_list:
print df.ix[values], "\n"
Ответ 5
Я искал способ опробовать несколько членов GroupBy obj - должен был ответить на опубликованный вопрос, чтобы сделать это.
создать групповой объект
grouped = df.groupby('some_key')
выбрать N датафреймов и захватить их признаки
sampled_df_i = random.sample(grouped.indicies, N)
захватить группы
df_list = map(lambda df_i: grouped.get_group(df_i), sampled_df_i)
по желанию - превратить все это обратно в один объект данных
sampled_df = pd.concat(df_list, axis=0, join='outer')