2017-09-03 50 views
2

我有兩個dataframes這樣的:高效串聯忽略後綴

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的dataframes df2的索引中的suf2。由於c1df1中的條目對於列A爲0,因此它應該出現在連接的數據幀中用於條目A_suf1A_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失敗等於因此

df2 = pd.DataFrame({"c3": range(15, 22), "c4": range(11, 18)}, index=["A_suf1", "B_suf2", "A_suf2", "C_suf2", "B_suf1", "D_suf1", "F_suf1"]) 

     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 
F_suf1 21 17 

問題是是否存在在那裏更有效和更通用的解決方案的工作,並且還分別非工作的情況下,。

回答

3

使用join通過MultiIndex產生分裂的df2indexreindexMultiindexdf1的:

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

非常漂亮(upvoted)!似乎有效地解決了我的兩個問題。 – Cleb

+0

@cᴏʟᴅsᴘᴇᴇᴅ - 是的,這是另一種解決方案。祝你好運! – jezrael

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 
+0

謝謝,似乎也很好,(upvoted);仍然需要弄清楚爲什麼「分裂」的鼻涕會出現在任何地方。 ;) – Cleb