多索引查找映射

时间:2019-08-30 19:20:22

标签: python pandas

我正在尝试创建一个新列,该列的值基于该行的2个索引。我在要查询的级别上具有2个具有等效多索引的数据框(但大小不相等)。对于第一个数据帧中的每一行,我想要与该行的索引匹配的第二个df的值。

我本来以为我可以使用.loc []并过滤掉索引值,但是我似乎无法用它来逐行更改输出。如果我不使用数据框对象,那么我会遍历整个过程来完成它。

我尝试使用.apply()方法,但是我不知道要传递给哪个函数。

创建具有相同结构的玩具数据:

#import pandas as pd
#import numpy as np
np.random.seed = 1

df = pd.DataFrame({'Aircraft':np.ones(15),
                    'DC':np.append(np.repeat(['A','B'], 7), 'C'),
                    'Test':np.array([10,10,10,10,10,10,20,10,10,10,10,10,10,20,10]),
                    'Record':np.array([1,2,3,4,5,6,1,1,2,3,4,5,6,1,1]),
                   # There are multiple "value" columns in my data, but I have simplified here 
                   'Value':np.random.random(15)
                   }
                  )
df.set_index(['Aircraft', 'DC', 'Test', 'Record'], inplace=True)
df.sort_index(inplace=True)

v = pd.DataFrame({'Aircraft':np.ones(7),
                  'DC':np.repeat('v',7),
                  'Test':np.array([10,10,10,10,10,10,20]),
                  'Record':np.array([1,2,3,4,5,6,1]),
                  'Value':np.random.random(7)
                 }
                )
v.set_index(['Aircraft', 'DC', 'Test', 'Record'], inplace=True)
v.sort_index(inplace=True)
df['v'] = df.apply(lambda x: v.loc[df.iloc[x]])

返回在多索引上建立索引的错误。

要将所有值设置为单个“ v”值:

df['v'] = float(v.loc[(slice(None), 'v', 10, 1), 'Value'])

所以输入看起来像这样:

--------------------------------------------
| Aircraft | DC | Test | Record | Value    |
|----------|----|------|--------|----------|
| 1.0      | A  | 10   | 1      | 0.847576 |
|          |    |      | 2      | 0.860720 |
|          |    |      | 3      | 0.017704 |
|          |    |      | 4      | 0.082040 |
|          |    |      | 5      | 0.583630 |
|          |    |      | 6      | 0.506363 |
|          |    | 20   | 1      | 0.844716 |
|          | B  | 10   | 1      | 0.698131 |
|          |    |      | 2      | 0.112444 |
|          |    |      | 3      | 0.718316 |
|          |    |      | 4      | 0.797613 |
|          |    |      | 5      | 0.129207 |
|          |    |      | 6      | 0.861329 |
|          |    | 20   | 1      | 0.535628 |
|          | C  | 10   | 1      | 0.121704 |
--------------------------------------------

--------------------------------------------
| Aircraft | DC | Test | Record | Value    |
|----------|----|------|--------|----------|
| 1.0      | v  | 10   | 1      | 0.961791 |
|          |    |      | 2      | 0.046681 |
|          |    |      | 3      | 0.913453 |
|          |    |      | 4      | 0.495924 |
|          |    |      | 5      | 0.149950 |
|          |    |      | 6      | 0.708635 |
|          |    | 20   | 1      | 0.874841 |
--------------------------------------------

在手术后,我想要这个:

| Aircraft | DC | Test | Record | Value    | v        |
|----------|----|------|--------|----------|----------|
| 1.0      | A  | 10   | 1      | 0.847576 | 0.961791 |
|          |    |      | 2      | 0.860720 | 0.046681 |
|          |    |      | 3      | 0.017704 | 0.913453 |
|          |    |      | 4      | 0.082040 | 0.495924 |
|          |    |      | 5      | 0.583630 | 0.149950 |
|          |    |      | 6      | 0.506363 | 0.708635 |
|          |    | 20   | 1      | 0.844716 | 0.874841 |
|          | B  | 10   | 1      | 0.698131 | 0.961791 |
|          |    |      | 2      | 0.112444 | 0.046681 |
|          |    |      | 3      | 0.718316 | 0.913453 |
|          |    |      | 4      | 0.797613 | 0.495924 |
|          |    |      | 5      | 0.129207 | 0.149950 |
|          |    |      | 6      | 0.861329 | 0.708635 |
|          |    | 20   | 1      | 0.535628 | 0.874841 |
|          | C  | 10   | 1      | 0.121704 | 0.961791 |

1 个答案:

答案 0 :(得分:0)

修改
正如您在熊猫0.23.4上一样,只需将droplevel更改为reset_index,并使用选项drop=True

df_result = (df.reset_index('DC').assign(v=v.reset_index('DC', drop=True))
               .set_index('DC', append=True)
               .reorder_levels(v.index.names))

原始
一种方法是将DC的索引df放入列中,并使用assign在其上创建新列,并使用reset_indexreorder_index

df_result = (df.reset_index('DC').assign(v=v.droplevel('DC'))
               .set_index('DC', append=True)
               .reorder_levels(v.index.names))

Out[1588]:
                            Value        v
Aircraft DC Test Record
1.0      A  10   1       0.847576  0.961791
                 2       0.860720  0.046681
                 3       0.017704  0.913453
                 4       0.082040  0.495924
                 5       0.583630  0.149950
                 6       0.506363  0.708635
            20   1       0.844716  0.874841
         B  10   1       0.698131  0.961791
                 2       0.112444  0.046681
                 3       0.718316  0.913453
                 4       0.797613  0.495924
                 5       0.129207  0.149950
                 6       0.861329  0.708635
            20   1       0.535628  0.874841
         C  10   1       0.121704  0.961791