高效连接忽略索引中的后缀

时间:2017-09-03 17:09:18

标签: python performance pandas dataframe concat

我有两个这样的数据框:

import pandas as pd

df1 = pd.DataFrame({"c1": range(5), "c2": range(1, 6)}, index=list("ABCDE"))
df2 = pd.DataFrame({"c3": range(15, 21), "c4": range(11, 17)}, index=["A_suf1", "B_suf2", "A_suf2", "C_suf2", "B_suf1", "D_suf1"])   

   c1  c2    
A   0   1
B   1   2
C   2   3
D   3   4
E   4   5

        c3  c4
A_suf1  15  11
B_suf2  16  12
A_suf2  17  13
C_suf2  18  14
B_suf1  19  15
D_suf1  20  16

我想变成

       c3  c4  c1
A_suf1  15  11   0
B_suf2  16  12   1
A_suf2  17  13   0
C_suf2  18  14   2
B_suf1  19  15   1
D_suf1  20  16   3

所以,我想在suf1的索引中连接独立于后缀suf2df2的数据帧。由于c1列中df1的{​​{1}}中的条目为0,因此它应显示在条目AA_suf1的连接数据框中。

我目前按如下方式实施:

A_suf2

给了我想要的输出。

但是,它需要相当慢的# store original name of index old_index = df2.index # temporary column which creates values which are in the the index of df1 df2['helper'] = df2.reset_index()["index"].apply(lambda x: x.split("_")[0]).tolist() # prepare concat df2 = df2.set_index("helper") # concat df_final = pd.concat([df2, df1.loc[:, "c1"]], join="inner", axis=1) # reset index to original values df_final.index = old_index ,如果apply中的索引条目不在df2中,它也会失败。例如,df1等于

的上述代码将失败
df2

因此,问题是,对于工作和非工作案例,是否分别有更有效和一般的解决方案。

2 个答案:

答案 0 :(得分:3)

使用MultiIndex index df2 Multiindex df1分段df2.index = df2.index.str.split('_', expand=True) print(df2) c3 c4 A suf1 15 11 B suf2 16 12 A suf2 17 13 C suf2 18 14 B suf1 19 15 D suf1 20 16 print (df1['c1'].reindex(df2.index,level=0)) A suf1 0 B suf2 1 A suf2 0 C suf2 2 B suf1 1 D suf1 3 Name: c1, dtype: int32 df = df2.join(df1['c1'].reindex(df2.index,level=0)) #convert MultiIndex to index df.index = df.index.map('_'.join) print (df) c3 c4 c1 A_suf1 15 11 0 B_suf2 16 12 1 A_suf2 17 13 0 C_suf2 18 14 2 B_suf1 19 15 1 D_suf1 20 16 3 df2 print (df) c3 c4 c1 A_suf1 15 11 0.0 B_suf2 16 12 1.0 A_suf2 17 13 0.0 C_suf2 18 14 2.0 B_suf1 19 15 1.0 D_suf1 20 16 3.0 F_suf1 21 17 NaN {/ 1}}使用join

{{1}}

另一个{{1}}获取:

{{1}}

答案 1 :(得分:1)

我认为您不需要转换为MultiIndex。您只需提取索引并使用df.locpd.concat即可加入。

idx = [x[0] for x in df2.index]
out = pd.concat([df2, df1.loc[idx, ['c1']].set_index(df2.index)], 1)
print(out)
        c3  c4  c1
A_suf1  15  11   0
B_suf2  16  12   1
A_suf2  17  13   0
C_suf2  18  14   2
B_suf1  19  15   1
D_suf1  20  16   3

对于你的第二个数据帧,我得到了

        c3  c4   c1
A_suf1  15  11  0.0
B_suf2  16  12  1.0
A_suf2  17  13  0.0
C_suf2  18  14  2.0
B_suf1  19  15  1.0
D_suf1  20  16  3.0
F_suf1  21  17  NaN

<强>性能

# converting to MultiIndex
100 loops, best of 3: 3.57 ms per loop

# using `df.loc` and `df.set_index`
1000 loops, best of 3: 1.53 ms per loop