Python 基于第二个索引在数据帧中保留行标签子集
给定一个层次索引包含三个级别(实验、试用、插槽)的数据帧和一个层次索引包含两个级别(实验、试用)的第二个数据帧,如何删除第一个数据帧中(实验、试用)不包含在第二个数据帧中的所有行 示例数据:Python 基于第二个索引在数据帧中保留行标签子集,python,pandas,Python,Pandas,给定一个层次索引包含三个级别(实验、试用、插槽)的数据帧和一个层次索引包含两个级别(实验、试用)的第二个数据帧,如何删除第一个数据帧中(实验、试用)不包含在第二个数据帧中的所有行 示例数据: 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,
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
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
一种方法是使用 您只需要将
合并的重新索引到您喜欢的任何位置(我无法从问题中准确判断)。应该工作的是
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>m>2不起作用,尽管它应该起作用。您的代码给出TypeError:initial_值必须是unicode或None,而不是str
。Hmm。我通过复制和粘贴StackOverflow问题中的代码重新测试,没有得到类型错误。我想知道是不是因为Python版本?这是在Python3和Pandas 0.16.1上实现的。我用Unicode的数据字符串更新了代码。谢谢!这是有道理的(我使用了一种类似的方法来使用join方法,但我认为我可以通过某种方式让reindex方法实现我想要的功能)。两个答案都是正确的(由Amy Tavory和JoeCondron发布)。处理此问题有多种方法,因为最明显的方法(df1.loc[df2.index]
)在当前版本的Pandas(0.16.1)中不起作用。请将此标记为正确,因为它包含了明显方法不起作用的解释。