如何获取多索引数据帧的前两个索引的dict

May*_*kar 7 python indexing numpy dataframe pandas

我有一个如下所示的数据框

在此输入图像描述

我想知道是否存在一种在pandas中创建python dict的最快方法,它将保存如下数据

table = {2: [4, 5, 6, 7, 8 ...], 4: [1, 2, 3, 4, ...]}
Run Code Online (Sandbox Code Playgroud)

这里的键是用户ID,值是唯一的日期列表.

这可以在core python的早期完成,但是想知道是否有一个基于pandas或numpy的方法来快速计算.我需要一个快速解决方案,当这个数据框变大时,它可以很好地扩展

编辑1:表演

所需时间:每循环14.3 ms±134μs(7次运行的平均值±标准差,每次100次循环)

levels = pd.DataFrame({k: df.index.get_level_values(k) for k in range(2)})

table = levels.drop_duplicates()\
              .groupby(0)[1].apply(list)\
              .to_dict()

print(table)
Run Code Online (Sandbox Code Playgroud)

采取的时间:每循环17.4 ms±105μs(7次运行的平均值±标准差,每次100次循环)

res.reset_index().drop_duplicates(['user_id','date']).groupby('user_id')['date'].apply(list).to_dict()
Run Code Online (Sandbox Code Playgroud)

采取的时间:每回路294 ms±12.8 ms(平均值±标准偏差,7次运行,每次1次循环)

a = {k: list(pd.unique(list(zip(*g))[1])) 
     for k, g in groupby(df.index.values.tolist(), itemgetter(0))}
print (a)
Run Code Online (Sandbox Code Playgroud)

采取时间:每循环15 ms±187μs(平均值±标准偏差,7次运行,每次100次循环)

pd.Series(res.index.get_level_values(1), index=res.index.get_level_values(0)).groupby(level=0).apply(set).to_dict()
Run Code Online (Sandbox Code Playgroud)

编辑2:再次进行基准测试

错误的结果

idx = df.index.droplevel(-1).drop_duplicates()
l1, l2 = idx.levels
mapping = defaultdict(list)
for i, j in zip(l1, l2):
    mapping[i].append(j)
Run Code Online (Sandbox Code Playgroud)

改进的定时:每个循环14.6 ms±58.8μs(7次运行的平均值±标准偏差,每次100次循环)

a = {k: list(set(list(zip(*g))[1])) 
     for k, g in groupby(res.index.values.tolist(), itemgetter(0))}
Run Code Online (Sandbox Code Playgroud)

jpp*_*jpp 4

这是使用drop_duplicates+的一种解决方案groupby

levels = pd.DataFrame({k: df.index.get_level_values(k) for k in range(2)})

table = levels.drop_duplicates()\
              .groupby(0)[1].apply(list)\
              .to_dict()

print(table)

{1: [2, 3], 2: [8, 9]}
Run Code Online (Sandbox Code Playgroud)

设置

df = pd.DataFrame([[1, 2, 0, 3], [1, 2, 1, 4], [1, 3, 1, 5],
                   [2, 8, 1, 3], [2, 8, 1, 4], [2, 9, 2, 5]],
                  columns=['col1', 'col2', 'col3', 'col4'])

df = df.set_index(['col1', 'col2', 'col3'])

print(df)

                col4
col1 col2 col3      
1    2    0        3
          1        4
     3    1        5
2    8    1        3
          1        4
     9    2        5
Run Code Online (Sandbox Code Playgroud)