DataFrame.lookup用于多索引DataFrame中的值

时间:2017-11-16 09:35:14

标签: python pandas

我正努力复制this solution多列索引 数据帧。

鉴于此df:

>>> import pandas as pd
>>> import numpy as np
>>> 
>>> # given dataframe
>>> arrays = [np.array(['REF',  'A1', 'A1', 'A2', 'A2']),
>>>           np.array(['absmax', 'min', 'max', 'min', 'max'])]
>>> values = np.array([[-0.1, -0.11, 0.8, -0.7, 0.8],
>>>           [0.05, -0.2, 0.01, -0.23, 0.07],
>>>           [-0.07, -0.15, 0.23, -0.09, 0.01]])
>>> df = pd.DataFrame(values, columns=arrays).sort_index(axis=1)
>>> print(df)

     A1          A2          REF
    max   min   max   min absmax
0  0.80 -0.11  0.80 -0.70  -0.10
1  0.01 -0.20  0.07 -0.23   0.05
2  0.23 -0.15  0.01 -0.09  -0.07

我需要为所有列Ai创建一个可复制的子列absmax ('Ai', 'min')('Ai', 'max'),具体取决于('REF', 'absmax')的符号。 提供以前的DataFrame,我希望:

      A1                 A2                REF
  absmax   max   min absmax   max   min absmax
0  -0.11  0.80 -0.11  -0.70  0.80 -0.70  -0.10
1   0.01  0.01 -0.20   0.07  0.07 -0.23   0.05
2  -0.15  0.23 -0.15  -0.09  0.01 -0.09  -0.07

为实现这一目标,我首先创建一个检索相关的vec列 子栏名:

>>> # retrieve value to read based on REF/absmax sign
>>> df[('REF', 'vec')] = np.where(df['REF', 'absmax']<0, 'min', 'max')
>>> print(df.sort_index(axis=1))
     A1          A2          REF     
    max   min   max   min absmax  vec
0  0.80 -0.11  0.80 -0.70  -0.10  min
1  0.01 -0.20  0.07 -0.23   0.05  max
2  0.23 -0.15  0.01 -0.09  -0.07  min

尝试为'A1'分配相关值(知道我可以拥有一堆'Ai'列):

>>> # assign value
>>> df[('A1', 'absmax')] = df.lookup(df.index, df[('A1', df[('REF', 'vec')])])
>>> df.sort_index(axis=1, inplace=True)
>>> print(df)
---------------------------------------------------------------------
TypeError                           Traceback (most recent call last)
[...]
TypeError: '('A1', 0    min
1    max
2    min
Name: (REF, vec), dtype: object)' is an invalid key

哪个有道理。知道如何解决这个问题吗?

PS:

>>> print('pandas %s' % pd.__version__)
>>> print('numpy %s' % np.__version__)
pandas 0.20.3
numpy 1.13.1

1 个答案:

答案 0 :(得分:0)

一种方法

chdir("/home");

使用ref = df[('REF', 'absmax')] vec = np.array(['min', 'max'])[ref.ge(0).astype(int)] lu = lambda d, vec: d.assign(absmax=d.lookup(d.index, vec)) df.filter(like='A').stack(0).groupby(level=1).apply(lu, vec=vec) \ .unstack().swaplevel(0, 1, 1).sort_index(1).join(ref) A1 A2 REF absmax max min absmax max min absmax 0 -0.11 0.80 -0.11 -0.70 0.80 -0.70 -0.10 1 0.01 0.01 -0.20 0.07 0.07 -0.23 0.05 2 -0.15 0.23 -0.15 -0.09 0.01 -0.09 -0.07 代替drop

,我可以更明确
filter