Slice Pandas dataframe по меткам, отсутствующим в списке
У меня есть pandas
dataframe, df
.
Я хочу выбрать все индексы в df
, которые не в списке, blacklist.
Теперь я использую понимание списка для создания желаемых меток на срезе.
ix=[i for i in df.index if i not in blacklist]
df_select=df.loc[ix]
Хорошо работает, но может быть неуклюжим, если мне нужно делать это часто.
Есть ли лучший способ сделать это?
Ответы
Ответ 1
Используйте isin
в индексе и инвертируйте логический индекс для выбора метки:
In [239]:
df = pd.DataFrame({'a':np.random.randn(5)})
df
Out[239]:
a
0 -0.548275
1 -0.411741
2 -1.187369
3 1.028967
4 -2.755030
In [240]:
t = [2,4]
df.loc[~df.index.isin(t)]
Out[240]:
a
0 -0.548275
1 -0.411741
3 1.028967
Ответ 2
Вы можете использовать set()
, чтобы создать разницу между вашими исходными индексами и теми, которые вы хотите удалить:
df.loc[set(df.index) - set(blacklist)]
У этого есть преимущество быть экономным, а также быть более легким для чтения, чем понимание списка.
Ответ 3
import pandas as pd
df = pd.DataFrame(data=[5,6,7,8], index=[1,2,3,4], columns=['D',])
blacklist = [2,3]
#your current way ...
ix=[i for i in df.index if i not in blacklist]
df_select=df.loc[ix]
# use a mask
mask = [True if x else False for x in df.index if x not in blacklist]
df.loc[mask]
http://pandas.pydata.org/pandas-docs/dev/indexing.html#indexing-label
на самом деле loc и iloc берут булевский массив, в этом случае mask
. с этого момента вы можете повторно использовать эту маску и должны быть более эффективными.
Ответ 4
Благодаря ASGM; Я обнаружил, что мне нужно включить набор в список, чтобы он работал с MultiIndex:
mi1 = pd.MultiIndex.from_tuples([("a", 1), ("a", 2), ("b", 1), ("b", 2)])
df1 = pd.DataFrame(data={"aaa":[1,2,3,4]}, index=mi1)
setValid = set(df1.index) - set([("a", 2)])
df1.loc[list(setValid)] # works
df1.loc[setValid] # fails
(извините, не могу комментировать, недостаточно rep)