从多索引中选择时如何避免应用连锁?

时间:2019-07-17 08:56:22

标签: python pandas dataframe select multi-index

我有一个这样的数据框:

import numpy as np
import pandas as pd


df = pd.DataFrame({
    'ind1': list('AAABBBCCC'),
    'ind2': list(map(int, list('123123123'))),
    'val1': [0, 1, 2, -1, -4, -5, 10, 11, 4],
    'val2': [0.1, 0.2, -0.2, 0.1, 0.2, 0.2, -0.1, 2, 0.1]
})

df = df.set_index(['ind1', 'ind2'])

           val1  val2
ind1 ind2            
A    1        0   0.1
     2        1   0.2
     3        2  -0.2
B    1       -1   0.1
     2       -4   0.2
     3       -5   0.2
C    1       10  -0.1
     2       11   2.0
     3        4   0.1

我要选择val1中值之间的差的绝对值不断增加的所有条目。

我目前的操作如下:

m_incr = (
    df.groupby('ind1')['val1']
      .apply(lambda x: np.diff(abs(x)))
      .apply(lambda x: all(eli > 0 for eli in x))
)

df_incr = df[m_incr[df.index.get_level_values('ind1')].values]

这给了我想要的结果:

           val1  val2
ind1 ind2            
A    1        0   0.1
     2        1   0.2
     3        2  -0.2
B    1       -1   0.1
     2       -4   0.2
     3       -5   0.2

我的问题是,是否有更直接/有效的方法来避免链接的apply

2 个答案:

答案 0 :(得分:2)

使用GroupBy.transform返回select count(*) from [Uneek Clothing Company Ltd$Sales Invoice Line] where [Sell-to Customer No_] = 'wor07' and [Posting Date] between '01/01/2019' and '12/31/2019' and Amount!=0 ,其大小与原始Series相同:

DataFrame

然后使用boolean indexing按掩码过滤:

mask = df.groupby('ind1')['val1'].transform(lambda x: (np.diff(abs(x)) > 0).all())

一起:

print (df[mask])

print (df[df.groupby('ind1')['val1'].transform(lambda x: (np.diff(abs(x)) > 0).all())])

详细信息

           val1  val2
ind1 ind2            
A    1        0   0.1
     2        1   0.2
     3        2  -0.2
B    1       -1   0.1
     2       -4   0.2
     3       -5   0.2

答案 1 :(得分:1)

或使用:

print(df[df.groupby('ind1')['val1'].transform(lambda x: x.abs().is_monotonic).astype(bool)])