我正努力复制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
答案 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