Добавить определенное количество переменных из одной группы в другую - PullRequest
0 голосов
/ 06 августа 2020

У меня есть pandas фрейм данных, в котором я разбил object одинаковых type на группы определенного числа (например, 3). Например, группа ball_1 содержит 3 уникальных объекта одного типа: soccer, basket и bouncy. Остальные объекты попадают в группу ball_2, которая в данном случае имеет только 1 объект tennis.

Для групп, содержащих менее 3 уникальных объектов, я хотел бы заполнить их первые k уникальных объектов первой группы. Например, группа ball_2 будет заполнена tennis, а затем soccer и basket из группы ball_1. Таким образом, цель состоит в том, чтобы все группы имели одинаковое количество уникальных объектов.

# chunk into groups of 3
N = 3
g = df.groupby('type')['object'].transform(lambda x: pd.factorize(x)[0]) // N + 1
df['group'] = df['type'].str.cat(g.astype(str), '_')

# identify which groups need more objects
for name, batch in df.groupby(['group']):
    subset = df[df.group.isin([name])]
    batch = batch.assign(check = subset['object'].nunique() < 3)
    batch = batch.assign(need = 3 - subset['object'].nunique())
    needmore = batch.loc[batch['check'] == True]
    if needmore.empty:
          continue 
    print('{} needs {} more objects'.format(batch['group'].unique(), batch['need'].unique()))

Текущий df (этот игрушечный набор данных с выбранными столбцами, но в реальном наборе данных больше столбцов)

     type  object  index    group
0    ball  soccer      1   ball_1
1    ball  soccer      2   ball_1
2    ball  basket      1   ball_1
3    ball  bouncy      1   ball_1
4    ball  tennis      1   ball_2
5    ball  tennis      2   ball_2
6   chair  office      1  chair_1
7   chair  office      2  chair_1
8   chair  office      3  chair_1
9   chair  lounge      1  chair_1
10  chair  dining      1  chair_1
... ...    ...         ......

Требуемый df (есть объекты, добавленные в группу ball_2)

     type  object  index    group
0    ball  soccer      1   ball_1
1    ball  soccer      2   ball_1
2    ball  basket      1   ball_1
3    ball  bouncy      1   ball_1
4    ball  tennis      1   ball_2
5    ball  tennis      2   ball_2
6    ball  soccer      1   ball_2
7    ball  soccer      2   ball_2
8    ball  basket      1   ball_2
9    chair office      1  chair_1
10   chair office      2  chair_1
11   chair office      3  chair_1
12   chair lounge      1  chair_1
13   chair dining      1  chair_1
... ...    ...         ......

1 Ответ

1 голос
/ 06 августа 2020

Вы можете попробовать это:

def addfisrtgroup(x):
    missing=np.arange(3-x.nunique().object)
    typegroup=x.iloc[0,0]
    msk=np.isin(df.loc[df.group.eq(f'{typegroup}_1')].object.factorize()[0],missing)
    return pd.concat([x,df.loc[df.group.eq(f'{typegroup}_1')][msk]])


temp=df.groupby('group')
       .apply(lambda x: addfirstgroup(x) if x.nunique().object<3 else x)
       .drop(columns='group')


groups=temp.index.get_level_values(0).to_frame().reset_index(drop=True)

pd.concat([temp.reset_index(drop=True), groups],1)

Вывод:

     type  object  index    group
0    ball  soccer      1   ball_1
1    ball  soccer      2   ball_1
2    ball  basket      1   ball_1
3    ball  bouncy      1   ball_1
4    ball  tennis      1   ball_2
5    ball  tennis      2   ball_2
6    ball  soccer      1   ball_2
7    ball  soccer      2   ball_2
8    ball  basket      1   ball_2
9   chair  office      1  chair_1
10  chair  office      2  chair_1
11  chair  office      3  chair_1
12  chair  lounge      1  chair_1
13  chair  dining      1  chair_1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...