Добавить Pandas дизъюнкцию 2-х фреймов данных к первому фрейму данных - PullRequest
0 голосов
/ 29 сентября 2018

Имеются 2 таблицы панд, оба с 3 столбцами id, x и y координаты.Таким образом, несколько строк одного и того же 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, df1 и df2 имеют похожие графики, но их порядок отличается от таблицы к таблице.В этом случае, например, df1 первый график - это df2 график секунд.Теперь df2 имеет 4-й путь, которого нет в df1.В этом случае 4-й путь должен быть обнаружен и добавлен к df1.Таким образом, я хочу получить пересечение таблицы 2 панд и добавить дизъюнкцию обоих к первой таблице, с условием, что id, так сказать, порядок путей может отличаться друг от друга.

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Импорт:

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

Примечание: Почему id_x становится float?

Fill 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'})

Пожалуйста, не забудьте поставить галочку рядом с выбранным ответом.

0 голосов
/ 29 сентября 2018

Маврикий, попробуйте этот код:

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

Я думаю, что это можно сделать более простым и питоническим, но я думаю, чтомного и до сих пор не знаю, как =)

И я думаю, следует проверить идентификаторы не то же самое в df1 и df2, прежде чем добавлять один df к другому (в конце).Я мог бы добавить это позже.

Этот код делает то, что вы хотите?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...