【问题标题】:Efficient and faster implementation of finding and matching unique values in a pandas dataframe在 Pandas 数据框中高效、快速地查找和匹配唯一值
【发布时间】: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' 列中提到的值。 此外,由于我必须处理非常大的数据集,您能否建议更快的实现。

【问题讨论】:

    标签: python python-3.x performance pandas indexing


    【解决方案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 指出的那样,这将是一个大数据集,而现实世界的数据中充满了这些。但我同意你有一个观点!我会编辑它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 2019-01-04
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多