我有 2 个数据框,如下所示:
df1 = pd.DataFrame({'A': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'],
'B': ['C1', 'C1', 'C1', 'C2', 'C2', 'C2', 'C2', 'C2'],
'rank': [2, 5, 1, 8, 6, 3, 4, 7]})
Out[3]:
A B rank
0 A C1 2
1 B C1 5
2 C C1 1
3 D C2 8
4 E C2 6
5 F C2 3
6 G C2 4
7 H C2 7
df2 = pd.DataFrame({'B': ['C1', 'C1', 'C1', 'C2'],
'C': [1, 2, 3, 4]})
Out[6]:
B C
0 C1 1
1 C1 2
2 C1 3
3 C2 4
我想选择 df1 中排名最高的 3 个行(按“排名”列),但每组(B 列)最多只能选择 4 个名称,这需要包括每组中的行数df2.
生成的数据框应如下所示:
A B rank
2 C C1 1
5 F C2 3
6 G C2 4
逻辑:
组 C1 的 df2 中的行数为 3(在 df1 中从该组中最多再留下 1 行可供选择),C2 的数量为 1(从 df1 中最多留下 3 行可供选择)
项目C的排名最高,因此被选中,现在C1组的总数为4 F 项和 G 项排在第二位,属于 C2 组,总数为 3,因此小于 4
我尝试了以下方法:
df1.sort_values('rank').groupby('B').head(4).head(5)
但这限制在 B 中最多选择 4 行组,只选择 df1 中的行并忽略 df2
答案 0 :(得分:1)
这是一个想法:
max_per_group = 4
# maximal rows to pick from each group
max_sizes = max_per_group - df2.groupby('B').size()
# 4 rows from each group
heads = df1.sort_values('rank').groupby('B').head(max_per_group)
# enumerate the rows within each group
enum = heads.groupby('B').cumcount()
# output
heads[enum<heads['B'].map(sizes).fillna(max_per_group)].head(3)
输出:
A B rank
2 C C1 1
5 F C2 3
6 G C2 4
答案 1 :(得分:1)
首先按组找出剩余的数量:
In [5]: (
...: df1.sort_values('rank').groupby('B').apply(
...: lambda x: x.sort_values('rank').head(remaining.get(x.name, 4))
...: ).sort_values('rank').iloc[:3].reset_index('B', drop=True)
...: )
Out[5]:
A B rank
2 C C1 1
5 F C2 3
6 G C2 4
然后,从 groupby 中每个排序的组中选择该数字:
>>> import subprocess
>>> command = "echo 123" # your command here.
>>> result = subprocess.run(command, text=True, shell=True, check=True, capture_output=True)
>>> user = 'unknown'
>>> print (user)
unknown
>>> if result.returncode == 0:
... user = result.stdout.strip()
...
>>> print (user)
123
>>>