Pandas dataframe, удаляйте строки между 2 строками, которые имеют одинаковые значения в некоторых столбцах - PullRequest
0 голосов
/ 03 ноября 2018

с учетом данных панелей Panda, как бы я удалить все строки, которые находятся между 2 строк, которые имеют одинаковые значения в 2 конкретных столбцах. В моем случае у меня есть столбцы x,y and id. Я хотел бы, чтобы пара x-y дважды появлялась в кадре данных, чтобы удалить все строки, которые лежат между этими 2.

Пример:

import pandas as pd                      
df1 = pd.DataFrame({'x':[1,2,3,2,1,3,4], 
                    'y':[1,2,3,4,3,3,4],
                   'id':[1,2,3,4,5,6,7]})
                             ^     ^     

Как видите, пара значений x=3,y=3 появляется дважды в кадре данных, один раз в id=3, один раз в id=6. Как я могу определить эти строки и отбросить все строки между ними? Чтобы я мог получить это например:

df1 = pd.DataFrame({'x':[1,2,3,4], 
                    'y':[1,2,3,4],
                   'id':[1,2,3,7]})

Фрейм данных также может быть таким, чтобы было больше «дубликатов», как в моем следующем примере, пара 4,2. Я хочу выделить внешние дубликаты, чтобы при удалении строк между ними все остальные дважды или более появляющиеся строки также были удалены. Например:

 df1 = pd.DataFrame({'x':[1,2,3,4,1,4,3,4], 
                     'y':[1,2,3,2,3,2,3,4],
                    'id':[1,2,3,4,5,6,7,8]})               
                              ^ ^   ^ ^              
                            out in in out          
 #should become:    
 df1 = pd.DataFrame({'x':[1,2,3,4], 
                     'y':[1,2,3,4], 
                    'id':[1,2,3,8]})

Для моего примера это должно вызвать своего рода устранение петли графа, который я представляю с фреймом данных. Как бы я это реализовал?

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Одно из возможных решений:

Давайте начнем с создания вашего DataFrame (здесь я пропустил необходимый импорт):

d = {'id': [1,2,3,4,5,6,7,8], 'x': [1,2,3,4,1,4,3,4], 'y': [1,2,3,2,3,2,3,4]}
df = pd.DataFrame(data=d)

Обратите внимание, что значения индекса являются последовательными числами (от 0), которые будут использоваться позже.

Затем мы должны найти дублированные строки, помечающие все экземпляры ( keep = False ):

dups = df[df.duplicated(subset=['x', 'y'], keep=False)]

Затем эти дубликаты должны быть сгруппированы в x и y :

gr = dups.groupby(['x', 'y'])

Затем следует добавить номер группы, к которой принадлежит конкретная строка. до df как, например, grpNo столбец.

df['grpNo'] = gr.ngroup()

Следующий шаг - найти первый и последний индекс строки, которая были сгруппированы в первой группе (с группой № == 0) и сохранены в ind1 и ind2.

ind1 = df[df['grpNo'] == 0].index[0]
ind2 = df[df['grpNo'] == 0].index[-1]

Затем мы находим список значений индекса для удаления:

indToDel = df[(df.index > ind1) & (df.index <= ind2)].index

Чтобы выполнить фактическое удаление строк, мы должны выполнить:

df.drop(indToDel, inplace=True)

И последний шаг - удалить столбец grpNo, который больше не нужен.

df.drop('grpNo', axis=1, inplace=True)

Результат:

   id  x  y
0   1  1  1
1   2  2  2
2   3  3  3
7   8  4  4

Таким образом, весь сценарий может быть следующим:

import pandas as pd

d = {'id': [1,2,3,4,5,6,7,8], 'x': [1,2,3,4,1,4,3,4], 'y': [1,2,3,2,3,2,3,4]}
df = pd.DataFrame(data=d)
dups = df[df.duplicated(subset=['x', 'y'], keep=False)]
gr = dups.groupby(['x', 'y'])
df['grpNo'] = gr.ngroup()
ind1 = df[df['grpNo'] == 0].index[0]
ind2 = df[df['grpNo'] == 0].index[-1]
indToDel = df[(df.index > ind1) & (df.index <= ind2)].index
df.drop(indToDel, inplace=True)
df.drop('grpNo', axis=1, inplace=True)
print(df)
0 голосов
/ 03 ноября 2018

Это работает для обоих ваших примеров, хотя и не уверен, что обобщает все примеры, которые вы имеете в виду:

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