如何根据值计数过滤熊猫 DataFrame?

Posted

技术标签:

【中文标题】如何根据值计数过滤熊猫 DataFrame?【英文标题】:How do I filter a pandas DataFrame based on value counts? 【发布时间】:2015-07-02 10:17:51 【问题描述】:

我正在使用 Python 处理视频游戏的 pandas DataFrame,每个游戏都有一个类型。我正在尝试删除在 DataFrame 中出现次数少于某些类型的任何视频游戏,但我不知道该怎么做。我确实找到了似乎相关的a *** question,但我根本无法破译解决方案(可能是因为我从未听说过 R 并且我对函数式编程的记忆充其量是生疏的)。

帮助?

【问题讨论】:

【参考方案1】:

另外,如果有人想要过滤并拥有“计数”列:

attr = 'A'
limit = 10
df2 = df.groupby(attr)[attr].agg(count='count')
df2 = df2.loc[df2['count'] > limit].reset_index()
print(df2)

#outputs rows with grouped 'A' count > 10 and columns ==> index, count, A

【讨论】:

【参考方案2】:

@jezael 解决方案效果很好,这是一种基于值计数的不同过滤方法:

例如,如果数据集是:

df = pd.DataFrame('a': [1,2,3,3,1,6], 'b': [11,2,33,4,55,6])

将计数转换并保存为字典

ount_freq = dict(df['a'].value_counts())

创建一个新列并复制目标列,将字典映射到新创建的列

df['count_freq'] = df['a']
df['count_freq'] = df['count_freq'].map(count_freq)

现在我们有了一个带有计数频率的新列,您现在可以使用此列轻松定义阈值和过滤器。

df[df.count_freq>1]

【讨论】:

【参考方案3】:

性能更好的解决方案应该是GroupBy.transformsize 用于将每组计数到具有与原始df 相同大小的系列,因此可以通过boolean indexing 过滤:

df1 = df[df.groupby("A")['A'].transform('size') > 1]

或将Series.mapSeries.value_counts 一起使用:

df1 = df[df['A'].map(df['A'].value_counts()) > 1]

【讨论】:

对于性能方面的价值,我在这里通过%%timeit 运行Series.map 解决方案与上面的groupby.filter 解决方案,结果如下(在主要是JSON字符串数据的数据帧上,分组字符串 ID 列):Series map: 2.34 ms ± 254 µs per loopGroupby.filter: 269 ms ± 41.3 ms per loop。所以Series.map 解决方案要快得多 多列组成的分组是什么?【参考方案4】:

使用groupby filter:

In [11]: df = pd.DataFrame([[1, 2], [1, 4], [5, 6]], columns=['A', 'B'])

In [12]: df
Out[12]:
   A  B
0  1  2
1  1  4
2  5  6

In [13]: df.groupby("A").filter(lambda x: len(x) > 1)
Out[13]:
   A  B
0  1  2
1  1  4

我推荐阅读split-combine-section of the docs。

【讨论】:

我们甚至可以按 MultiIndex 级别进行分组:groupby(level=...)。正是我所需要的 这对我不起作用 - 我收到以下错误,不知道该怎么做:“过滤器函数返回一个系列,但期望一个标量布尔值”@Andy Hayden

以上是关于如何根据值计数过滤熊猫 DataFrame?的主要内容,如果未能解决你的问题,请参考以下文章

在熊猫数据框中按日期和计数值分组

熊猫如何按时间段过滤DataFrame

如何根据来自不同列的多个值过滤熊猫表? [复制]

熊猫计数分组值[重复]

从过滤的熊猫数据框中获取整数索引值

获取回答熊猫过滤器的所有值的索引