根据另一个DataFrame的索引选择特定行

46

我有一个DataFrame,我想选择只包含df1.index索引值的行。

例如:

In [96]: df
Out[96]:
   A  B  C  D
1  1  4  9  1
2  4  5  0  2
3  5  5  1  0
22 1  3  9  6

并且这些是索引

In[96]:df1.index
Out[96]:
Int64Index([  1,   3,   4,   5,   6,   7,  22,  28,  29,  32,], dtype='int64', length=253)

我想要这个输出:

In [96]: df
Out[96]:
   A  B  C  D
1  1  4  9  1
3  5  5  1  0
22 1  3  9  6
2个回答

76

使用 isin 函数:

df = df[df.index.isin(df1.index)]

或者获取所有交集的索引,并使用 loc 进行选择:

df = df.loc[df.index & df1.index]
df = df.loc[np.intersect1d(df.index, df1.index)]
df = df.loc[df.index.intersection(df1.index)]

print (df)
    A  B  C  D
1   1  4  9  1
3   5  5  1  0
22  1  3  9  6

编辑:

我尝试了解决方案:df = df.loc[df1.index]。你认为这个解决方案正确吗?

这个解决方案是不正确的:

df = df.loc[df1.index]
print (df)

      A    B    C    D
1   1.0  4.0  9.0  1.0
3   5.0  5.0  1.0  0.0
4   NaN  NaN  NaN  NaN
5   NaN  NaN  NaN  NaN
6   NaN  NaN  NaN  NaN
7   NaN  NaN  NaN  NaN
22  1.0  3.0  9.0  6.0
28  NaN  NaN  NaN  NaN
29  NaN  NaN  NaN  NaN
32  NaN  NaN  NaN  NaN
C:/Dropbox/work-joy/so/_t/t.py:23: FutureWarning: 
Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike
  print (df)

我尝试了这个解决方案:df = df.loc[df1.index]。你认为这个解决方案正确吗? - giupardeb
1
@giupardeb - 我测试了一下,已经添加到回答中了。请查看。 - jezrael
1
我想补充一下,df = df.loc[df1.index] 不起作用。 - halo09876
2
@song0089 - 嗯,所以使用 df = df[df.index.isin(df1.index)] - jezrael
2
请注意,isin() 的使用方式可能会导致 dfdf1 的顺序不一致。 - DocOc

10

现在,将索引传递给.loc的行索引器/切片器是有效的,只需要确保同时指定列即可,例如:

df = df.loc[df1.index, :]  # works

而不是

df = df.loc[df1.index] # won't work

依我之见,这更符合使用 .loc 的预期方式,并且更加整洁/一致。


你是正确的,似乎开发人员已经更改了实现方式。 然而,现在如果您传入一个不存在的值列表,两者都会引发 KeyError 警告。 - Hansang
2
这个解决方案的优点是确保df和df1的顺序相同。 - DocOc
1
只有当df1的整个索引包含在df的索引中时,这才有效;被接受的答案没有这个限制。 - fantabolous

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接