基于第二个索引在pandas DataFrame中保留行标签的子集

时间:2015-06-08 19:24:20

标签: python pandas

如果DataFrame的分层索引包含三个级别(实验,试验,插槽),第二个DataFrame的分层索引包含两个级别(实验,试用),如何删除第一个DataFrame中的所有行(实验,试验)不包含在第二个数据框中?

示例数据:

from io import StringIO
import pandas as pd

df1_data = StringIO(u',experiment,trial,slot,token\n0,btn144a10_p_RDT,0,0,4.0\n1,btn144a10_p_RDT,0,1,14.0\n2,btn144a10_p_RDT,1,0,12.0\n3,btn144a10_p_RDT,1,1,14.0\n4,btn145a07_p_RDT,0,0,6.0\n5,btn145a07_p_RDT,0,1,19.0\n6,btn145a07_p_RDT,1,0,17.0\n7,btn145a07_p_RDT,1,1,13.0\n8,chn004b06_p_RDT,0,0,6.0\n9,chn004b06_p_RDT,0,1,8.0\n10,chn004b06_p_RDT,1,0,2.0\n11,chn004b06_p_RDT,1,1,5.0\n12,chn008a06_p_RDT,0,0,12.0\n13,chn008a06_p_RDT,0,1,14.0\n14,chn008a06_p_RDT,1,0,6.0\n15,chn008a06_p_RDT,1,1,4.0\n16,chn008b06_p_RDT,0,0,3.0\n17,chn008b06_p_RDT,0,1,13.0\n18,chn008b06_p_RDT,1,0,12.0\n19,chn008b06_p_RDT,1,1,19.0\n20,chn008c04_p_RDT,0,0,17.0\n21,chn008c04_p_RDT,0,1,2.0\n22,chn008c04_p_RDT,1,0,1.0\n23,chn008c04_p_RDT,1,1,6.0\n')
df1 = pd.DataFrame.from_csv(df1_data).set_index(['experiment', 'trial', 'slot'])

df2_data = StringIO(u',experiment,trial,target\n0,btn145a07_p_RDT,1,13\n1,chn004b06_p_RDT,1,9\n2,chn008a06_p_RDT,0,15\n3,chn008a06_p_RDT,1,15\n4,chn008b06_p_RDT,1,1\n5,chn008c04_p_RDT,1,12\n')
df2 = pd.DataFrame.from_csv(df2_data).set_index(['experiment', 'trial'])

第一个数据框如下所示:

                            token
experiment      trial slot       
btn144a10_p_RDT 0     0         4
                      1        14
                1     0        12
                      1        14
btn145a07_p_RDT 0     0         6
                      1        19
                1     0        17
                      1        13
chn004b06_p_RDT 0     0         6
                      1         8
                1     0         2
                      1         5
chn008a06_p_RDT 0     0        12
                      1        14
                1     0         6
                      1         4
chn008b06_p_RDT 0     0         3
                      1        13
                1     0        12
                      1        19
chn008c04_p_RDT 0     0        17
                      1         2
                1     0         1
                      1         6

第二个数据框如下所示:

                       target
experiment      trial        
btn145a07_p_RDT 1          13
chn004b06_p_RDT 1           9
chn008a06_p_RDT 0          15
                1          15
chn008b06_p_RDT 1           1
chn008c04_p_RDT 1          12

我想要的结果

                            token
experiment      trial slot       
btn145a07_p_RDT 1     0        17
                      1        13
chn004b06_p_RDT 1     0         2
                      1         5
chn008a06_p_RDT 0     0        12
                      1        14
                1     0         6
                      1         4
chn008b06_p_RDT 1     0        12
                      1        19
chn008c04_p_RDT 1     0         1
                      1         6

2 个答案:

答案 0 :(得分:2)

一种方法是使用merge

merged = pd.merge(
    df2.reset_index(),
    df1.reset_index(),
    left_on=['experiment', 'trial'],
    right_on=['experiment', 'trial'],
    how='left')

您只需将merged重新索引到您喜欢的任何内容(我无法从问题中准确说出来)。

答案 1 :(得分:1)

应该做些什么

df1.loc[df2.index] 

但是多索引仍然存在一些问题。工作是什么

df1.reset_index(2).loc[df2.index].set_index('slot', append=True)

这是一个关于这个问题的黑客攻击。注意

df1.loc[df2.index[:1]] 

给出了垃圾

df.loc[df2.index[0]] 

给出你所期望的。因此,将多个值从m级索引传递到n级索引,其中n> 1。 m> 2虽然不应该工作,但是不行。