将2个数据帧的熊猫分离附加到第一个数据帧

时间:2018-09-29 12:08:06

标签: python pandas join

给出2个熊猫表,它们都具有3列idxy坐标。因此,同一id的几行代表具有其x-y值的图形。如何找到第一个表中不存在但第二个表中不存在的路径并将它们附加到第一个表中?关键问题在于两个表中图形的顺序可能不同。

示例:

df1 = pd.DataFrame({'id':[1,1,2,2,2,3,3,3], 'x':[1,1,5,4,4,1,1,1], 'y':[1,2,4,4,3,4,5,6]})
df2 = pd.DataFrame({'id':[1,1,1,2,2,3,3,3,4,4,4], 'x':[1,1,1,1,1,5,4,4,10,10,9], 'y':[4,5,6,1,2,4,4,3,1,2,2]})

(df1   intersect df2  )  --------->  df1
id x y       id x y              id x y 
1  1 1       1  1 4              1  1 1 
1  1 2       1  1 5              1  1 2
2  5 4       1  1 6              2  5 4
2  4 4       2  1 1              2  4 4
2  4 3       2  1 2              2  4 3
3  1 4       3  5 4              3  1 4
3  1 5       3  4 4              3  1 5
3  1 6       3  4 3              3  1 6
             4  10 1             4  10 1
             4  10 2             4  10 2
             4   9 2             4   9 2 
Should become:
df1 = pd.DataFrame({'id':[1,1,2,2,2,3,3,3,4,4,4], 'x':[1,1,5,4,4,1,1,1,10,10,9], 'y':[1,2,4,4,3,4,5,6,1,2,2]})

id = 3之前,您可以看到df1df2具有相似的图形,但是它们的顺序在一个表与另一个表之间是不同的。在这种情况下,例如df1的第一张图是df2秒的图。现在df2的第四条路径不在df1中。在这种情况下,应该检测到第四条路径并将其附加到df1。像这样,我想得到2个pandas表的交集,并将两者的相加附加到第一个表上,条件是id,也就是说,路径的顺序可以不同于一个和另一个。

2 个答案:

答案 0 :(得分:2)

进口:

import pandas as pd

设置起始数据帧:

df1 = pd.DataFrame({'id':[1,1,2,2,2,3,3,3], 
                    'x':[1,1,5,4,4,1,1,1], 
                    'y':[1,2,4,4,3,4,5,6]})
df2 = pd.DataFrame({'id':[1,1,1,2,2,3,3,3,4,4,4], 
                    'x':[1,1,1,1,1,5,4,4,10,10,9], 
                    'y':[4,5,6,1,2,4,4,3,1,2,2]})

外部合并:

df_merged = df1.merge(df2, on=['x', 'y'], how='outer')

产生:

df_merged =

   id_x  x  y   id_y
0   1.0  1  1   2
1   1.0  1  2   2
2   2.0  5  4   3
3   2.0  4  4   3
4   2.0  4  3   3
5   3.0  1  4   1
6   3.0  1  5   1
7   3.0  1  6   1
8   NaN  10 1   4
9   NaN  10 2   4
10  NaN  9  2   4

注意:Why does id_x become floats?

填写NaN:

df_merged.id_x = df_merged.id_x.fillna(df_merged.id_y).astype('int')

产生:

df_merged = 

 id_x   x   y   id_y
0   1   1   1   2
1   1   1   2   2
2   2   5   4   3
3   2   4   4   3
4   2   4   3   3
5   3   1   4   1
6   3   1   5   1
7   3   1   6   1
8   4   10  1   4
9   4   10  2   4
10  4   9   2   4

拖放id_y

df_merged = df_merged.drop(['id_y'], axis=1)

产生:

df_merged = 

    id_x    x   y
0      1    1   1
1      1    1   2
2      2    5   4
3      2    4   4
4      2    4   3
5      3    1   4
6      3    1   5
7      3    1   6
8      4    10  1
9      4    10  2
10     4    9   2

id_x重命名为id

df_merged = df_merged.rename(columns={'id_x': 'id'})

产生:

df_merged = 

    id  x   y
0   1   1   1
1   1   1   2
2   2   5   4
3   2   4   4
4   2   4   3
5   3   1   4
6   3   1   5
7   3   1   6
8   4   10  1
9   4   10  2
10  4   9   2

最终程序是4行代码:

import pandas as pd

df1 = pd.DataFrame({'id':[1,1,2,2,2,3,3,3], 
                    'x':[1,1,5,4,4,1,1,1], 
                    'y':[1,2,4,4,3,4,5,6]})
df2 = pd.DataFrame({'id':[1,1,1,2,2,3,3,3,4,4,4], 
                    'x':[1,1,1,1,1,5,4,4,10,10,9], 
                    'y':[4,5,6,1,2,4,4,3,1,2,2]})

df_merged = df1.merge(df2, on=['x', 'y'], how='outer')
df_merged.id_x = df_merged.id_x.fillna(df_merged.id_y).astype('int')
df_merged = df_merged.drop(['id_y'], axis=1)
df_merged = df_merged.rename(columns={'id_x': 'id'})

请记住在所选答案旁边打勾。

答案 1 :(得分:0)

毛里求斯,请尝试以下代码:

df1 = pd.DataFrame({'id':[1,1,2,2,2,3,3,3], 'x':[1,1,5,4,4,1,1,1], 'y':[1,2,4,4,3,4,5,6]})
df2 = pd.DataFrame({'id':[1,1,1,2,2,3,3,3,4,4,4,5], 'x':[1,1,1,1,1,5,4,4,10,10,9,1], 'y':[4,5,6,1,2,4,4,3,1,2,2,2]})

df1_s = [{(x,y) for x, y in df1[['x','y']][df1.id==i].values} for i in df1.id.unique()]

def f(df2):
    data = {(x,y) for x, y in df2[['x','y']].values}
    if data not in df1_s:
        return True
    else:
        return False

check = df2.groupby('id').apply(f).apply(pd.Series)
ids = check[check[0]].index.values
df2 = df2.set_index('id').loc[ids].reset_index()

df1 = df1.append(df2)

OUT:

   id   x  y
0   1   1  1
1   1   1  2
2   2   5  4
3   2   4  4
4   2   4  3
5   3   1  4
6   3   1  5
7   3   1  6
0   4  10  1
1   4  10  2
2   4   9  2
3   5   1  2

我认为它可以更简单,更pythonic地完成,但我认为很多,但仍然不知道=)

我认为,在将一个df附加到另一个(最后)之前,应该检查df1和df2中的id是否不同。我可能会在以后添加。

此代码是否可以满足您的要求?