#python #pandas #indexing #series #drop
Вопрос:
Итак, у меня есть конкретная проблема, которую необходимо решить. Мне нужно удалить элементы, присутствующие в одной серии pandas (ser1), которые являются общими для другой серии pandas (ser2).
Я перепробовал кучу вещей, которые не работают, и самое близкое, что я смог найти, было с массивами, использующими функцию np.intersect1d(). Это работает для поиска общих значений, но когда я пытаюсь удалить индексы, равные этим значениям, я получаю кучу ошибок.
Я перепробовал кучу других вещей, которые на самом деле не сработали, и занимаюсь этим уже 3 часа, так что собираюсь сдаться.
вот две серии:
ser1 = pd.Series([1, 2, 3, 4, 5])
ser2 = pd.Series([4, 5, 6, 7, 8])
Результат должен быть:
print(ser1)
0 1
1 2
2 3
Я уверен, что есть простое решение.
Комментарии:
1. посмотрите на
Series.isin()
Ответ №1:
Используйте .isin
:
>>> ser1[~ser1.isin(ser2)]
0 1
1 2
2 3
dtype: int64
Версия numpy .setdiff1d
(и нет .intersect1d
)
>>> np.setdiff1d(ser1, ser2)
array([1, 2, 3])
Ответ №2:
Альтернатива numpy, np.isin
import pandas as pd
import numpy as np
ser1 = pd.Series([1, 2, 3, 4, 5])
ser2 = pd.Series([4, 5, 6, 7, 8])
res = ser1[~np.isin(ser1, ser2)]
print(res)
Микро-бенчмарк
import pandas as pd
import numpy as np
ser1 = pd.Series([1, 2, 3, 4, 5] * 100)
ser2 = pd.Series([4, 5, 6, 7, 8] * 10)
%timeit res = ser1[~np.isin(ser1, ser2)]
136 µs ± 2.56 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit res = ser1[~ser1.isin(ser2)]
209 µs ± 1.66 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit pd.Index(ser1).difference(ser2).to_series()
277 µs ± 1.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Комментарии:
1. Я думаю, вам также следует добавить набор python здесь
2. @sammywemmy Не уверен, как использовать set здесь, вы имеете в виду преобразование в set и обратно в series?
3.
set(ser1).difference(ser2)
… опасность с set заключается в том, что он неупорядочен4. Работает, спасибо за ваше время!
5. Набор @sammywemmy выполняется очень быстро, но не упорядочен. Для тех же значений это дает 29us
Ответ №3:
Вы можете использовать set notation — я не уверен в скорости, хотя по сравнению с isin:
pd.Index(ser1).difference(ser2).to_series()
Out[35]:
1 1
2 2
3 3
dtype: int64
Комментарии:
1. Это хорошо работает, спасибо, есть ли причина, по которой индекс новой серии не начинается с 0?
2. аааа… таким образом, индекс повторяется и как индекс, и как ряд. в рамках
to_series
метода вы можете вручную передать новый индекс. или просто reset_index3. Для сброса индекса я использовал: ser1 =
(pd.Index(ser1).difference(ser2).to_series()) ser1 = ser1.reset_index() print(ser1)
и он дал мне это в качестве ответа :Name: alphabets, dtype: object index 0 0 1 1 1 2 2 2 3 3
4. используйте
reset_index(drop=True)
5. Работает, спасибо за ваш ответ, очень признателен!