Python 将一定数量的变量从一个组添加到另一个组
我有一个pandas数据框,在该数据框中,我将相同类型的Python 将一定数量的变量从一个组添加到另一个组,python,pandas,dataframe,data-wrangling,Python,Pandas,Dataframe,Data Wrangling,我有一个pandas数据框,在该数据框中,我将相同类型的对象分为若干组(例如,3)。例如,组ball_1包含同一类型的3个唯一对象:soccer、basket和bouncy。剩余的对象进入组ball_2,在这种情况下,该组只有一个对象tentiles 对于包含少于3个唯一对象的组,我想用第一个组的前k个唯一对象填充它们。例如,组ball_2将填充网球,然后组ball_1中的足球和篮。因此,目标是使所有组具有相同数量的唯一对象 # chunk into groups of 3 N = 3 g =
对象
分为若干组(例如,3)。例如,组ball_1
包含同一类型的3个唯一对象:soccer
、basket
和bouncy
。剩余的对象进入组ball_2
,在这种情况下,该组只有一个对象tentiles
对于包含少于3个唯一对象的组,我想用第一个组的前k个唯一对象填充它们。例如,组ball_2
将填充网球
,然后组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(已将对象添加到组ball_2
)
你可以试试这个:
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)
不符合条件的组将始终填充第一组?第一组总是符合条件吗?@MrNobody33,是的!我还将它们分块,以便第一个组(如ball_1)具有完整的对象集(因此条件是它包含3个对象)。如果ball_x需要更多的对象,它将被ball_1中的对象填充。如果chair_x需要更多对象,它将由chair_1等填充。刚刚添加了一种方法@psychcoderThis非常适合单独添加
对象:)谢谢!很抱歉,如果我以前模棱两可(我现在意识到了这一点),那么您能提供一些建议,如何循环您的定义,以便将其推广到所有组吗?例如,如果chair_x需要更多的对象,它将由chair_1填充,等等。在我的示例中,恰好椅子平均分成3个。上面是一个玩具数据集,但我的真实数据集相当大,需要由其类型的第一组填充多个其他组。但真的非常感谢,再一次!为了再次澄清,当前代码将使用ball
中的对象填充小于3的任何其他组。但是,我的数据集将包含其他类型,如table
,当前正在填充ball\u 1
中的对象,而不是table\u 1
。谢谢!typegroup=x.iloc[0,0]
是否依赖于type
作为df的第一列?您的代码尚未推广到我的真实数据集,但我怀疑这是因为type
不是第一列。我试图用typegroup=x.iloc[0,27]
标识正确的列,尽管这不起作用。你有什么建议吗?试试这样:typegroup=x.reset\u index(drop=True)['type'][0]
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
... ... ... ......
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