根据值以批处理方式删除pandas数据帧行和列

时间:2017-09-14 21:06:16

标签: python pandas dataframe

背景:我有一个表示两点之间距离的矩阵。在此矩阵中,行和列都是数据点。例如:

   A   B   C
 A 0   999 3
 B 999 0   999
 C 3   999 0

在这个玩具示例中,让我们说出于某种原因我想放弃C,因为它远离任何其他点。所以我首先汇总计数:

df["far_count"] = df[df == 999].count()

然后批量删除它们:

df = df[df["far_count"] == 2]

在这个例子中,这看起来有点多余,但请想象我有很多像这样的数据点(比如大约10K)

上面批量删除的问题是我想在同一时间(而不仅仅是行)删除行和列,我不清楚如何优雅地执行此操作。一种天真的方法是获取这些数据点的列表并将其放入循环中然后:

for item in list:
  df.drop(item, axis=1).drop(item, axis=0)

但我想知道是否有更好的方法。 (如果我们可以跳过中间步骤far_count),则可以获得奖励

2 个答案:

答案 0 :(得分:2)

np.random.seed([3,14159])
idx = pd.Index(list('ABCDE'))
a = np.random.randint(3, size=(5, 5))
df = pd.DataFrame(
    a.T.dot(a) * (1 - np.eye(5, dtype=int)),
    idx, idx)

df

   A  B  C  D  E
A  0  4  2  4  2
B  4  0  1  5  2
C  2  1  0  2  6
D  4  5  2  0  3
E  2  2  6  3  0
l = ['A', 'C']
m = df.index.isin(l)

df.loc[~m, ~m]

   B  D  E
B  0  5  2
D  5  0  3
E  2  3  0

对于您的特定情况,因为数组是对称的,您只需要检查一个维度。

m = (df.values == 999).sum(0) == len(df) - 1

答案 1 :(得分:2)

In [66]: x = pd.DataFrame(np.triu(df), df.index, df.columns)

In [67]: x
Out[67]:
   A    B    C
A  0  999    3
B  0    0  999
C  0    0    0

In [68]: mask = x.ne(999).all(1) | x.ne(999).all(0)

In [69]: df.loc[mask, mask]
Out[69]:
   A  C
A  0  3
C  3  0