pandas Series.value_counts returns inconsistent order for equal count strings

ぃ、小莉子 提交于 2019-12-05 05:55:43

You have a few options to sort consistently given a series:

s = pd.Series(['a', 'b', 'a', 'c', 'c'])
c = s.value_counts()

sort by index

Use pd.Series.sort_index:

res = c.sort_index()

a    2
b    1
c    2
dtype: int64

sort by count (arbitrary for ties)

For descending counts, do nothing, as this is the default. Otherwise, you can use pd.Series.sort_values, which defaults to ascending=True. In either case, you should make no assumptions on how ties are handled.

res = c.sort_values()

b    1
c    2
a    2
dtype: int64

More efficiently, you can use c.iloc[::-1] to reverse the order.

sort by count and then by index

You can use numpy.lexsort to sort by count and then by index. Note the reverse order, i.e. -c.values is used first for sorting.

res = c.iloc[np.lexsort((c.index, -c.values))]

a    2
c    2
b    1
dtype: int64

Adding a reindex after value_counts

df.value_counts().reindex(df.unique())
Out[353]: 
a    1
b    1
dtype: int64

Update

s.value_counts().sort_index().sort_values()

You could use sort_index:

print(df.value_counts().sort_index())

Output:

a    1
b    1
dtype: int64

Please see the documentation if you want to use parameters (like ascending=True etc.)

sort_index vs reindex(df.unique()) (as suggested by @Wen) seem to be perform quite similar:

df.value_counts().sort_index():         1000 loops, best of 3: 636 µs per loop
df.value_counts().reindex(df.unique()): 1000 loops, best of 3: 880 µs per loop
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!