连接索引上的键列

时间:2017-01-13 12:40:01

标签: python pandas left-join

左右两个DataFrame。

left = pd.DataFrame({'C': ['C0', 'C1'],
                     'D': ['D0', 'D1']},
                     index=['K0', 'K1'])

right = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                      'B': ['B0', 'B1', 'B2', 'B3'],
                      'key': ['K0', 'K1', 'K0', 'K1']})

左:

enter image description here

右:

enter image description here

左框架键中的

也是索引的“k0,k1”,并且是唯一的。 在右边框中键是“k0,k1,k0,k1”,它们可以出现任意数量的时间。 问题是: 如何结合那些结果的框架:

enter image description here

2 个答案:

答案 0 :(得分:3)

首先需要pivot_table重新塑造right

right1 = right.pivot_table(index='key', 
                           columns=right.groupby('key').cumcount(),
                           aggfunc='first').sort_index(axis=1, level=1)
right1.columns = right1.columns.droplevel(0)
print (right1)
      0   0   1   1
key                
K0   A0  B0  A2  B2
K1   A1  B1  A3  B3

right1的另一个解决方案是groupbyGroupBy.first

g = right.groupby('key').cumcount()
right1 = right.groupby([right.key, g]).first().unstack().sort_index(axis=1, level=1)
right1.columns = right1.columns.droplevel(0)
print (right1)
      0   0   1   1
key                
K0   A0  B0  A2  B2
K1   A1  B1  A3  B3

最后一次使用concatinner加入或merge加入(如何='内部'可以省略,因为默认参数):

df = pd.concat([left, right1], axis=1, join='inner')
#assign default column names (0,1,2...)
df.columns = np.arange(len(df.columns))
df.index.name = None
print (df)
     0   1   2   3   4   5
K0  C0  D0  A0  B0  A2  B2
K1  C1  D1  A1  B1  A3  B3

df1 = pd.merge(left, right1, left_index=True, right_index=True)
#assign default column names (0,1,2...)
df1.columns = np.arange(len(df1.columns))
print (df1)
     0   1   2   3   4   5
K0  C0  D0  A0  B0  A2  B2
K1  C1  D1  A1  B1  A3  B3

答案 1 :(得分:1)

这是一个解决方案,它将键的所有值放入Series中的列表中,然后将其转换为DataFrame。对于更大的数据,它也更快。

right_flat = right.set_index('key').groupby(level='key').apply(lambda x: x.values.flatten().tolist())
left_flat = pd.Series(left.T.to_dict('list'))
all_flat = left_flat + right_flat
df_final = pd.concat([pd.Series(v, name=idx) for idx, v in all_flat.iteritems()], axis=1).T

速度测试

制作更大的数据

right = right.sample(100000, replace=True)

%%timeit
right_flat = right.set_index('key').groupby(level='key').apply(lambda x: x.values.flatten().tolist())
left_flat = pd.Series(left.T.to_dict('list'))
all_flat = left_flat + right_flat
df_final = pd.concat([pd.Series(v, name=idx) for idx, v in all_flat.iteritems()], axis=1).T

100个循环,最佳3:每循环29.1 ms

%%timeit
g = right.groupby('key').cumcount()
right1 = right.groupby([right.key, g]).first().unstack().sort_index(axis=1, level=1)
right1.columns = right1.columns.droplevel(0)
df = pd.concat([left, right1], axis=1, join='inner')
df.columns = np.arange(len(df.columns))
df.index.name = None

10个循环,最佳3:96循环每个循环