Удаление строки в df1, если пара значений столбцов не связана в другом df2 - PullRequest
1 голос
/ 08 апреля 2019

Учитывая df1 и df2, я хочу получить df3. Единственные столбцы / строки, которые я хочу сопоставить, это Pop и Homes . Я включил столбец данных Other , чтобы получить решение для произвольного количества столбцов.

df1
City        Pop  Homes Other
City_1      100      1     0
City_1      100      2     6
City_1      100      2     2
City_1      100      3     9
City_1      200      1     6
City_1      200      2     6
City_1      200      3     7
City_1      300      1     0

df2
City        Pop  Homes Other
City_1      100      1     0
City_1      100      2     6
City_1      100      2     2
City_1      100      8     9
City_1      200      1     6
City_1      200      2     6
City_1      800      3     7
City_1      800      8     0

df3
City        Pop  Homes Other
City_1      100      1     0
City_1      100      2     6
City_1      100      2     2
City_1      200      1     6
City_1      200      2     6

Я думал о группировке по городам, попам и домам, например df1.groupby (['City', 'Pop', 'Homes']), но тогда я не знаю, как отфильтровать неравенства Поп и Дома .

EDIT

Вот мой код, чтобы вы могли мне легче помочь.

df1_string = """City_1      100      1     0
City_1      100      2     6
City_1      100      2     2
City_1      100      3     9
City_1      200      1     6
City_1      200      2     6
City_1      200      3     7
City_1      300      1     0"""

df2_string = """City_1      100      1     0
City_1      100      2     6
City_1      100      2     2
City_1      100      8     9
City_1      200      1     6
City_1      200      2     6
City_1      800      3     7
City_1      800      8     0"""

df1 = pd.DataFrame([x.split() for x in df1_string.split('\n')], columns=['City', 'Pop', 'Homes', 'Other'])
df2 = pd.DataFrame([x.split() for x in df2_string.split('\n')], columns=['City', 'Pop', 'Homes', 'Other'])

df1_keys = [x for x in df1.groupby(['Pop', 'Homes']).groups.keys()]
df2_keys = [x for x in df2.groupby(['Pop', 'Homes']).groups.keys()]

print(df1_keys)
[('100', '1'), ('100', '2'), ('100', '3'), ('200', '1'), ('200', '2'), ('200', '3'), ('300', '1')]
print(df2_keys)
[('100', '1'), ('100', '2'), ('100', '8'), ('200', '1'), ('200', '2'), ('800', '3'), ('800', '8')]

Отсюда может показаться простым отфильтровать пары групп, которые не равны, но я не могу решить это. Я пробовал:

df1 = df1[df1.groupby(['Pop', 'Homes']).groups.keys().isin(df2.groupby(['Pop', 'Homes']).groups.keys())]

И другие варианты этого, когда это не сработало, - но я чувствую, что оно близко к работе.

РЕШЕНИЕ

df1.set_index(['Pop', 'Homes'], inplace=True)
df2.set_index(['Pop', 'Homes'], inplace=True)

df1 = df1[df2.index.isin(df1.index)]

df1.reset_index(inplace=True)

Ответы [ 2 ]

2 голосов
/ 08 апреля 2019

IIUC и если город, поп, дом находятся в индексе, то вы можете использовать isin:

df2[df2.index.isin(df1.index)]

Выход:

                 Count
City  Pop Homes       
City1 100 20       152
          24       184
      200 41       163
          42       163
0 голосов
/ 08 апреля 2019

Создание мультииндексов для фреймов данных и внутреннее соединение для пересечения.

import pandas as pd
import numpy as np


df1_string = """City_1      100      1     0
City_1      100      2     6
City_1      100      2     2
City_1      100      3     9
City_1      200      1     6
City_1      200      2     6
City_1      200      3     7
City_1      300      1     0"""

df2_string = """City_1      100      1     0
City_1      100      2     6
City_1      100      2     2
City_1      100      8     9
City_1      200      1     6
City_1      200      2     6
City_1      800      3     7
City_1      800      8     0"""

df1 = pd.DataFrame([x.split() for x in df1_string.split('\n')], columns=['City', 'Pop', 'Homes', 'Other'])
df2 = pd.DataFrame([x.split() for x in df2_string.split('\n')], columns=['City', 'Pop', 'Homes', 'Other'])

# Dataframes benefit from having indexes that reflect that tabular data
df1.set_index(['City', 'Pop', 'Homes'], inplace=True)
df2.set_index(['City', 'Pop', 'Homes'], inplace=True)

# an inner join on the multiindex will provide the intersaction of the two
result = df1.join(df2, how='inner', on=['City', 'Pop', 'Homes'], lsuffix='_l', rsuffix='_r')

# a join provides all of the joined columns
result.reset_index(inplace=True)
result.drop(['Other_r'], axis=1, inplace=True)
result.columns = ['City', 'Pop', 'Homes', 'Other']

print(result)

...