首页 > 解决方案 > python pandas按值计数重新标记值

问题描述

给定以下示例:

example = pd.DataFrame({'y':[1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,-1,-1,-1]})

我想按频率计数按降序重新标记这些值。所以我希望用 0 替换案例数量最多的值(例如 1),然后用 1 替换下一个最大的 bin,以此类推所有的值。需要注意的是,我想忽略值为 -1 的情况。如果我运行value_counts(),我可以看到:

y 
 1    10
 2     4
-1     3
 0     2
dtype: int64

但我想要一个 pythonic 和非 hacky/clean 解决方案来创建以下内容:

    y
0   0
1   0
2   0
3   0
4   0
5   0
6   0
7   0
8   0
9   0
10  1
11  1
12  1
13  1
14  2
15  2
16 -1
17 -1
18 -1

y 
 0    10
 1     4
-1     3
 2     2
dtype: int64

(理想情况下,我也保留旧列以保持良好的记录)。我可以遍历每个值,检查它是否不是 -1,然后value_counts()用迭代号替换它,但这感觉维护成本很高。有没有一种干净的方法来实现它?

标签: pythonpandas

解决方案


Series.map由索引创建的字典从Seriesafter Series.value_countswithout使用-1

s = example['y'].value_counts().drop(-1)
d = {v:k for k, v in dict(enumerate(s.index)).items()}

或者:

s = example['y'].value_counts().drop(-1)
d = dict(zip(s.index, range(len(s))))

m = example['y'].ne(-1)
example.loc[m, 'y'] = example.loc[m, 'y'].map(d)

print (example)
  y
0   0
1   0
2   0
3   0
4   0
5   0
6   0
7   0
8   0
9   0
10  1
11  1
12  1
13  1
14  2
15  2
16 -1
17 -1
18 -1

另一个想法是增加-1价值:-1dictionary

s = example['y'].value_counts().drop(-1)
d = {**{-1:-1}, **dict(zip(s.index, range(len(s))))}

example['y'] = example['y'].map(d)

推荐阅读