我正在使用这样的Pandas数据框:
col1 col2 id name
0 1 2 1 harry
1 2 3 1 harry
2 3 4 2 harry
3 4 5 3 harry
4 5 6 4 harry
5 1 9 6 jane
6 2 10 6 jane
7 3 11 7 jane
8 4 12 7 jane
9 5 12 8 jane
我想创建一个新的数据框,其中对于每个name
,我使用唯一的id
值获取前3行。
例如,对于harry
,这将是第0、2和3行。由于第1行具有与第0行相同的ID,因此排除了行1。
示例数据帧的正确输出是:
col1 col2 id name
0 1 2 1 harry
2 3 4 2 harry
3 4 5 3 harry
5 1 9 6 jane
7 3 11 7 jane
9 5 12 8 jane
示例数据帧由以下代码给出:
example = pd.DataFrame({"col1":[1,2,3,4,5, 1,2,3,4,5], "id":[1,1,2,3,4, 6, 6, 7, 7, 8],
"col2":[2,3,4,5,6, 9, 10, 11, 12, 12],
"name":["harry", "harry", "harry", "harry", "harry", "jane",
"jane","jane","jane","jane",]})
此代码有效,但是非常丑陋,无法向量化:
result_df = pd.DataFrame(columns=example.columns)
names_to_ids = {}
for i, row in example.iterrows():
curr_name = row["name"]
curr_id = row["id"]
print curr_name, curr_id
if curr_name not in names_to_ids:
result_df = result_df.append(row)
names_to_ids[curr_name] = [curr_id]
elif len(names_to_ids[curr_name]) < 3 and curr_id not in names_to_ids[curr_name]:
result_df = result_df.append(row)
names_to_ids[curr_name].append(curr_id)
答案 0 :(得分:3)
使用drop_duplicates
和head
:
df.drop_duplicates(['id', 'name']).groupby('name').head(3)
col1 col2 id name
0 1 2 1 harry
2 3 4 2 harry
3 4 5 3 harry
5 1 9 6 jane
7 3 11 7 jane
9 5 12 8 jane
答案 1 :(得分:0)
另一种方法是使用双groupby
和head
In [183]: df.groupby(['name', 'id']).head(1).groupby('name').head(3)
Out[183]:
col1 col2 id name
0 1 2 1 harry
2 3 4 2 harry
3 4 5 3 harry
5 1 9 6 jane
7 3 11 7 jane
9 5 12 8 jane
答案 2 :(得分:0)
使用drop_duplicates
,然后使用GroupBy
+ cumcount
:
res = df.drop_duplicates(['id', 'name'])
res = res.loc[res.groupby('name').cumcount().lt(3)]
print(res)
col1 col2 id name
0 1 2 1 harry
2 3 4 2 harry
3 4 5 3 harry
5 1 9 6 jane
7 3 11 7 jane
9 5 12 8 jane