Возвращать строки на основе самого последнего увеличения значения из других столбцов Python - PullRequest
0 голосов
/ 16 октября 2018

Название этого вопроса немного сбивает с толку, чтобы писать кратко.

У меня есть pandas df, который содержит integers и соответствующий key Column.Когда значение присутствует в key Column, я хочу вернуть самое последнее увеличение integers по сравнению с другим Columns.

Для df ниже key Column равен [Area].Когда X находится в [Area], я хочу найти самое недавнее увеличение целых чисел от Columns ['ST_A','PG_A','ST_B','PG_B'].

import pandas as pd

d = ({
    'ST_A' : [0,0,0,0,0,1,1,1,1],                 
    'PG_A' : [0,0,0,1,1,1,2,2,2],                 
    'ST_B' : [0,1,1,1,1,1,1,1,1],  
    'PG_B' : [0,0,0,0,0,0,0,1,1],   
    'Area' : ['','','X','','X','','','','X'],                 
     })

df = pd.DataFrame(data = d)

Вывод:

   ST_A  PG_A  ST_B  PG_B Area
0     0     0     0     0     
1     0     0     1     0     
2     0     0     1     0    X
3     0     1     1     0     
4     0     1     1     0    X
5     1     1     1     0     
6     1     2     1     0     
7     1     2     1     1     
8     1     2     1     1    X

Я пыталсяиспользовать df = df.loc[(df['Area'] == 'X')], но это возвращает rows, где находится X.Мне нужно что-то, что использует X, чтобы вернуть самую последнюю строку, где было увеличение Columns ['ST_A','PG_A','ST_B','PG_B'].

Я также попытался:

cols = ['ST_A','PG_A','ST_B','PG_B']
df[cols] = df[cols].diff()
df = df.fillna(0.)
df = df.loc[(df[cols] == 1).any(axis=1)]

Это возвращает все rows, где произошло увеличение Columns ['ST_A','PG_A','ST_B','PG_B'].Не самое последнее увеличение до X в ['Area'].

Предполагаемый результат:

   ST_A  PG_A  ST_B  PG_B Area
1     0     0     1     0     
3     0     1     1     0     
7     1     2     1     1  

Имеет ли этот вопрос смысл или мне нужно его упростить?

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Я думаю, что вы можете использовать NumPy здесь через np.searchsorted:

import numpy as np

increases = np.where(df.iloc[:, :-1].diff().gt(0).max(1))[0]
marks = np.where(df['Area'].eq('X'))[0]

idx = increases[np.searchsorted(increases, marks) - 1]

res = df.iloc[idx]

print(res)

   ST_A  PG_A  ST_B  PG_B Area
1     0     0     1     0     
3     0     1     1     0     
7     1     2     1     1    
0 голосов
/ 16 октября 2018

Не эффективно, но работает, такой большой кусок кода, который довольно медленный:

indexes=np.where(df['Area']=='X')[0].tolist()
indexes2=list(map((1).__add__,np.where(df[df.columns[:-1]].sum(axis=1) < df[df.columns[:-1]].shift(-1).sum(axis=1).sort_index())[0].tolist()))
l=[]
for i in indexes:
   if min(indexes2,key=lambda x: abs(x-i)) in l:
      l.append(min(indexes2,key=lambda x: abs(x-i))-2)
   else:
      l.append(min(indexes2,key=lambda x: abs(x-i)))
print(df.iloc[l].sort_index())

Вывод:

  Area  PG_A  PG_B  ST_A  ST_B
1          0     0     0     1
3          1     0     0     1
7          2     1     1     1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...