Разделить каждую строку на несколько групп с помощью Pandas groupby?

57
5

Поэтому у меня есть DataFrame, который выглядит следующим образом:

In [5]: import pandas as pd, numpy as np
np.random.seed(seed=43525)
descriptors = 'abcdefghi'
df = pd.DataFrame([{'Value':np.random.randint(0,100),
'Group':descriptors[np.random.randint(0, len(descriptors)):
np.random.randint(0, len(descriptors))]} for i in range(0,10)])
print(df)

Group Value
0 4
1 abc 37
2 efgh 99
3 a 67
4 37
5 52
6 46
7 b 41
8 d 17
9 36

Каждый символ в списке дескрипторов должен стать его собственной группой (вместе с нулевой группой). Как я мог выполнить groupby чтобы выполнить это?

Таким образом, группа "a" будет содержать индексы 1 и 3, группа "b" будет содержать индексы 1 и 7 и т.д. Это довольно нестандартный подход к использованию groupby (если это может быть выполнено с ним вообще) m не уверен, как действовать.

спросил(а) 2014-07-01T16:36:00+04:00 6 лет, 3 месяца назад
1
Решение
58

Похоже, что вы действительно хотите, это MultiIndex. groupby предоставит вам уникальные группы - в основном то, что у вас есть в столбце Group, но MultiIndex приблизит вас к тому, что вам кажется.

Например,

descriptors = 'abcdefghi'
df = pd.DataFrame([{'Value':np.random.randint(0,100),
'Group':descriptors[np.random.randint(0, len(descriptors)):
np.random.randint(0, len(descriptors))]} for i in range(0,10)])

groups = df.Group.map(lambda x : tuple(desc if desc in x else '-' for desc in descriptors))
df.index = pd.MultiIndex.from_tuples(groups.values, names=list(descriptors))
df

Out[4]:
Group Value
a b c d e f g h i
- - - - - - - - - 4
a b c - - - - - - abc 37
- - - - e f g h - efgh 99
a - - - - - - - - a 67
- - - - - - - - - 37
- 52
- 46
b - - - - - - - b 41
- - d - - - - - d 17
- - - - - - 36

Теперь вы можете выбрать данные с помощью df.xs или df.ix Например, если вы хотите, чтобы все группы имели "a" и "c", вы можете использовать

df.xs(('a', 'c'), level=('a', 'c'))
Out[5]:
Group Value
b d e f g h i
b - - - - - - abc 37

Аналогичным образом, вы можете выбрать все группы, которые содержат "b",

df.xs('b', level='b')
Out[7]:
Group Value
a c d e f g h i
a c - - - - - - abc 37
- - - - - - - - b 41

Чтобы выбрать негруппированные строки, вы можете использовать

df.sort_index(inplace=True) #index must be sorted 
df.ix[('-',) * len(descriptors)]
Out[10]:
Group Value
a b c d e f g h i
- - - - - - - - - 4
- 37
- 52
- 46
- 36

Примечание. Я использовал символ "-" как символ заполнения, но это не обязательно.

ответил(а) 2014-07-01T18:58:00+04:00 6 лет, 3 месяца назад
57

Составив ответ Эдчума, я придумал следующее. Структура похожа на groupby объекта groupby:

indices = {}
for val in np.unique(''.join(df.Group.values)):
indices[val] = df[df.Group.str.contains(val)]
print(indices)

Предоставляя следующий плохо отформатированный, но правильный ответ:

{'a':   Group  Value
1 abc 37
3 a 67, 'c': Group Value
1 abc 37, 'b': Group Value
1 abc 37
7 b 41, 'e': Group Value
2 efgh 99, 'd': Group Value
8 d 17, 'g': Group Value
2 efgh 99, 'f': Group Value
2 efgh 99, 'h': Group Value
2 efgh 99}

ответил(а) 2014-07-01T17:12:00+04:00 6 лет, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема