如何根据值计数过滤熊猫 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.transform
和size
用于将每组计数到具有与原始df
相同大小的系列,因此可以通过boolean indexing
过滤:
df1 = df[df.groupby("A")['A'].transform('size') > 1]
或将Series.map
与Series.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 loop
、Groupby.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?的主要内容,如果未能解决你的问题,请参考以下文章