我有一个这样的数据框:

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

我的问题是是否有一种更直接/更有效的方法来避免链式applys。

最佳答案

使用GroupBy.transform返回Series与原始DataFrame大小相同:

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

然后使用boolean indexing按掩码过滤:
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

详细信息:
print (mask)
ind1  ind2
A     1        True
      2        True
      3        True
B     1        True
      2        True
      3        True
C     1       False
      2       False
      3       False
Name: val1, dtype: bool

关于python - 从多索引中选择时如何避免链式应用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57072110/

10-11 07:49