【发布时间】:2017-05-06 23:02:16
【问题描述】:
如何从 Pandas DataFrame 中删除(删除)行,其中行没有由索引唯一标识?
澄清我所说的唯一标识的含义:查询索引时,会返回多个值。
我可以制作一个掩码,当用作df.loc 的参数时,它会正确返回目标行,但我无法使其与df.drop 一起使用。
示例代码:
打印函数的输出包含在注释中。
from __future__ import print_function
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame(
data=np.random.randint(0, 10, size=(7, 3)),
index=[['u01', 'u01', 'u01', 'u02', 'u02', 'u03', 'u03'], ['C', 'C', 'C', 'C', 'T', 'T', 'T']],
columns=['foo', 'bar', 'baz'])
df.index.names = ['user', 'comType']
print(df)
# foo bar baz
# user comType
# u01 C 5 0 3
# C 3 7 9
# C 3 5 2
# u02 C 4 7 6
# T 8 8 1
# u03 T 6 7 7
# T 8 1 5
mask = (df.baz > 8) | (df.baz < 2)
print(mask)
# user comType
# u01 C False
# C True
# C False
# u02 C False
# T True
# u03 T False
# T False
# Name: baz, dtype: bool
print(df.loc[mask])
# foo bar baz
# user comType
# u01 C 3 7 9
# u02 T 8 8 1
df2 = df.drop(mask.index[mask.values]) # Drops all rows of user user u01, one row of user u02
print(df2)
# foo bar baz
# user comType
# u02 C 4 7 6
# u03 T 6 7 7
# T 8 1 5
df3 = df.drop(mask) # Doesn't do anything
print(df3)
# foo bar baz
# user comType
# u01 C 5 0 3
# C 3 7 9
# C 3 5 2
# u02 C 4 7 6
# T 8 8 1
# u03 T 6 7 7
# T 8 1 5
快速提示:如果您想在自己的机器上运行代码,我建议用这些行替换打印功能,否则很难输出辨认对方:
print('df', df, sep=" =\n\n", end="\n"*5)
print('mask', mask, sep=" =\n\n", end="\n"*5)
print('df.loc[mask]', df.loc[mask], sep=" =\n\n", end="\n"*5)
print('df2', df2, sep=" =\n\n", end="\n"*5)
print('df3', df3, sep=" =\n\n", end="\n"*5)
【问题讨论】:
-
你认为通过重复删除索引吗?
print(df.reset_index().drop_duplicates(subset=['user','comType']).set_index(['user','comType']))? -
或类似
print (df.groupby(level=[0,1]).first())或print (df.groupby(level=[0,1]).last())? -
不,我不需要删除重复项,只需删除一些“坏行”。我主要使用索引作为查询数据子集的数据集的一种方式,所以我可以将索引查询映射到多个值。
-
对不起,你是在
df[mask == False]之后吗? -
或者更好
print (df[~mask])?
标签: python pandas indexing multi-index