在 Pandas 数据框中高效、快速地查找和匹配唯一值

Posted

技术标签:

【中文标题】在 Pandas 数据框中高效、快速地查找和匹配唯一值【英文标题】:Efficient and faster implementation of finding and matching unique values in a pandas dataframe 【发布时间】:2019-01-13 07:31:47 【问题描述】:

关于以下 Pandas 数据框,

idx = pd.MultiIndex.from_product([['A001', 'B001','C001'],
                                  ['0', '1', '2']],
                                 names=['ID', 'Entries'])
col = ['A', 'B']

df = pd.DataFrame('-', idx, col)
df.loc['A001', 'A'] = [10,10,10]
df.loc['A001', 'B'] = [90,84,70]
df.loc['B001', 'A'] = [10,20,30]
df.loc['B001', 'B'] = [70,86,67]
df.loc['C001', 'A'] = [20,20,20]
df.loc['C001', 'B'] = [98,81,72]
df.loc['D001', 'A'] = [20,20,10]
df.loc['D001', 'B'] = [68,71,92]
#df is a dataframe
df

我很想知道在其“A”列中包含一组或列表中的所有值的 ID。让我们定义一个值为 [10,20] 的列表。在这种情况下,我应该得到位置 'B001' 和 'D001' 作为答案,因为这两个位置都有在它们的 'A' 列中提到的值。 此外,由于我必须处理非常大的数据集,您能否建议更快的实现。

【问题讨论】:

【参考方案1】:

您可以使用set.intersection 进行计算,并使用pd.Index.get_level_values 提取第一级索引:

search = 10, 20

idx = (set(df[df['A'] == i].index.get_level_values(0)) for i in search)

res = set.intersection(*idx)

【讨论】:

set.intersection 真的很快。这个在大数据集上的实现每个循环花费了 71 ns ± 5.34 ns(平均值 ± 标准差,7 次运行,每次 1000000 次循环)。【参考方案2】:

基本上——

search_list = 10,20
op = df.groupby(level=0)['A'].apply(lambda x: search_list.issubset(set(x))).reset_index()
print(op[op['A']]['ID'])

感谢@Ben.T 删除了不必要的unique()

输出

1    B001
Name: ID, dtype: object

说明

df.groupby(level=0)['A']level 0 分组并为您提供列表 -

ID
A001            [10]
B001    [10, 20, 30]
C001            [20]

接下来,对于这些列表中的每一个,我们将其转换为一个集合并检查search_list 是否是一个子集。

ID
A001    False
B001     True
C001    False

它返回一个布尔值Series,然后可以用作掩码 -

print(op[op['A']]['ID'])

最终输出 -

1    B001

【讨论】:

我认为unique 没有必要,因为您在apply 之后使用set(x) :) @Ben.T 以防万一,正如 OP 指出的那样,这将是一个大数据集,而现实世界的数据中充满了这些。但我同意你有一个观点!我会编辑它

以上是关于在 Pandas 数据框中高效、快速地查找和匹配唯一值的主要内容,如果未能解决你的问题,请参考以下文章

numpy 数组中非唯一行的快速组合,映射到列(即快速数据透视表问题,没有 Pandas)

Pandas - 查找和索引与行序列模式匹配的行

从 pandas 数据框列中查找所有正则表达式匹配项

材料树——查找后期项目(在 Pandas 数据框中)

在 Pandas 数据框中查找和替换子字符串忽略大小写

pandas介绍