返回基于其他列python的值最近增加的行

时间:2018-10-16 07:31:15

标签: python pandas sorting numpy dataframe

这个问题的标题简明扼要。

我有pandas df,其中包含integers和相关的key Column。当存在key Column中的值时,我要返回integers与其他Columns中最近的增加。

对于下面的dfkey 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)]

这将返回 all 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 :(得分:0)

效率不高,但是可以工作,所以很大一部分代码有点慢:

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

答案 1 :(得分:0)

我相信您可以通过np.searchsorted在此处使用NumPy:

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