Pandas 使用多列的 groupby 函数
Pandas groupby function using multiple columns
这类似于以下内容,但是我想进一步提出一个问题:
我有这个数据框:
Group Value Part Ratio
0 A 6373 10 0.637300
1 A 2512 10 0.251200
2 A 603 10 0.060300
3 A 512 10 0.051200
4 B 5200 20 0.472727
5 B 4800 20 0.436364
6 B 501 20 0.045545
7 B 499 20 0.045364
这个函数同时使用了 'Ratio' 和 'Part' 列,我想将其应用到每个 'Group':
def allocation(df, ratio, part):
k = df[part].max()
frac, results = np.array(np.modf(k * df[ratio]))
remainder = int(k - results.sum())
indices = np.argsort(frac)[::-1]
results[indices[0:remainder]] += 1
return results.astype(int)
请注意,我的函数与我在顶部提到的问题中显示的函数之间的区别在于,我的函数 returns 是整个组的值数组,而不是单个值。我尝试了以下方法:
data.groupby('Group', group_keys=False).apply(allocation, ratio='Ratio', part='Part')
Out[67]:
Group
A [6, 2, 1, 1]
B [9, 9, 1, 1]
dtype: object
这些数字是正确的。但是,我需要输出是一个系列,我可以将其分配回原始数据帧,这样它看起来像这样:
Group Value Part Ratio Allocate
0 A 6373 10 0.637300 6
1 A 2512 10 0.251200 2
2 A 603 10 0.060300 1
3 A 512 10 0.051200 1
4 B 5200 20 0.472727 9
5 B 4800 20 0.436364 9
6 B 501 20 0.045545 1
7 B 499 20 0.045364 1
我该怎么做?使用的方法是否正确?
通常在使用apply
时出现,使用自定义功能,我们可以使用concatenate
来修复它
s=df.groupby('Group', group_keys=False).apply(allocation, ratio='Ratio', part='Part').values
df['Allocate']=np.concatenate(s)
df
Out[71]:
Group Value Part Ratio Allocate
0 A 6373 10 0.637300 6
1 A 2512 10 0.251200 2
2 A 603 10 0.060300 1
3 A 512 10 0.051200 1
4 B 5200 20 0.472727 9
5 B 4800 20 0.436364 9
6 B 501 20 0.045545 1
7 B 499 20 0.045364 1
要以 pandas 方式进行,您可以使用分配函数 return a DataFrame
或 Series
:
def allocation(df, ratio, part):
k = df[part].max()
frac, results = np.array(np.modf(k * df[ratio]))
remainder = int(k - results.sum())
indices = np.argsort(frac)[::-1]
results[indices[0:remainder]] += 1
df['Allocate'] = results.astype(int)
return df
然后groupby.apply
直接给你想要的
In [61]: df.groupby('Group', group_keys=False).apply(allocation, ratio='Ratio', part='Part')
Out[61]:
Group Value Part Ratio Allocate
0 A 6373 10 0.6373 6
1 A 2512 10 0.2512 2
2 A 603 10 0.0603 1
3 A 512 10 0.0512 1
4 B 5200 20 0.4727 9
5 B 4800 20 0.4364 9
6 B 501 20 0.0455 1
7 B 499 20 0.0454 1
即使原始数据框未按 Group
排序,此方法也有效。
在 df2 = pd.concat([df.iloc[:2], df.iloc[6:], df.iloc[2:6]])
上试用
这类似于以下内容,但是我想进一步提出一个问题:
我有这个数据框:
Group Value Part Ratio
0 A 6373 10 0.637300
1 A 2512 10 0.251200
2 A 603 10 0.060300
3 A 512 10 0.051200
4 B 5200 20 0.472727
5 B 4800 20 0.436364
6 B 501 20 0.045545
7 B 499 20 0.045364
这个函数同时使用了 'Ratio' 和 'Part' 列,我想将其应用到每个 'Group':
def allocation(df, ratio, part):
k = df[part].max()
frac, results = np.array(np.modf(k * df[ratio]))
remainder = int(k - results.sum())
indices = np.argsort(frac)[::-1]
results[indices[0:remainder]] += 1
return results.astype(int)
请注意,我的函数与我在顶部提到的问题中显示的函数之间的区别在于,我的函数 returns 是整个组的值数组,而不是单个值。我尝试了以下方法:
data.groupby('Group', group_keys=False).apply(allocation, ratio='Ratio', part='Part')
Out[67]:
Group
A [6, 2, 1, 1]
B [9, 9, 1, 1]
dtype: object
这些数字是正确的。但是,我需要输出是一个系列,我可以将其分配回原始数据帧,这样它看起来像这样:
Group Value Part Ratio Allocate
0 A 6373 10 0.637300 6
1 A 2512 10 0.251200 2
2 A 603 10 0.060300 1
3 A 512 10 0.051200 1
4 B 5200 20 0.472727 9
5 B 4800 20 0.436364 9
6 B 501 20 0.045545 1
7 B 499 20 0.045364 1
我该怎么做?使用的方法是否正确?
通常在使用apply
时出现,使用自定义功能,我们可以使用concatenate
s=df.groupby('Group', group_keys=False).apply(allocation, ratio='Ratio', part='Part').values
df['Allocate']=np.concatenate(s)
df
Out[71]:
Group Value Part Ratio Allocate
0 A 6373 10 0.637300 6
1 A 2512 10 0.251200 2
2 A 603 10 0.060300 1
3 A 512 10 0.051200 1
4 B 5200 20 0.472727 9
5 B 4800 20 0.436364 9
6 B 501 20 0.045545 1
7 B 499 20 0.045364 1
要以 pandas 方式进行,您可以使用分配函数 return a DataFrame
或 Series
:
def allocation(df, ratio, part):
k = df[part].max()
frac, results = np.array(np.modf(k * df[ratio]))
remainder = int(k - results.sum())
indices = np.argsort(frac)[::-1]
results[indices[0:remainder]] += 1
df['Allocate'] = results.astype(int)
return df
然后groupby.apply
直接给你想要的
In [61]: df.groupby('Group', group_keys=False).apply(allocation, ratio='Ratio', part='Part')
Out[61]:
Group Value Part Ratio Allocate
0 A 6373 10 0.6373 6
1 A 2512 10 0.2512 2
2 A 603 10 0.0603 1
3 A 512 10 0.0512 1
4 B 5200 20 0.4727 9
5 B 4800 20 0.4364 9
6 B 501 20 0.0455 1
7 B 499 20 0.0454 1
即使原始数据框未按 Group
排序,此方法也有效。
在 df2 = pd.concat([df.iloc[:2], df.iloc[6:], df.iloc[2:6]])