Фильтровать элементы списка в Серии списков по серии логических масок - PullRequest
0 голосов
/ 16 декабря 2018

У меня есть две Series, которые выглядят следующим образом: Series 1 имеет список str, тогда как массив numpie Series 2 с логическими выражениями в нем.

Но у меня около 50 000 строк, и я хочу видеть значенияна основе логического выражения типа

ser1 = pd.Series([[1, 2, 3], [4], [7, 8]])
ser2 = pd.Series([[True, False, True], [False], [True, True]])

ser1

0    [1, 2, 3]
1          [4]
2       [7, 8]
dtype: object

ser2

0    [True, False, True]
1                [False]
2           [True, True]
dtype: object

И,

Output=[1,3],[],[7,8],....

Я попробовал два метода, но не могу их правильно построить, первый получает слишком много времени, когда второй не работает.

output=[]
for i in range(len(Series1)):
output.append(Series1.apply(np.array)[i][Series2[i]])

output=[Series1.apply(lambda x: x[i]) for i in Series2]

Есть ли у вас какие-либо предположения, что я могу получить этот вывод?
Большое вам спасибо.

1 Ответ

0 голосов
/ 16 декабря 2018
ser1 = pd.Series([[1, 2, 3], [4], [7, 8]])
ser2 = pd.Series([[True, False, True], [False], [True, True]])

Есть несколько способов сделать это, но я бы не рекомендовал apply.Один из вариантов - zip серии и фильтрации с использованием логической индексации numpy:

pd.Series([np.array(x)[y] for x, y in zip(ser1, ser2)])

0    [1, 3]
1        []
2    [7, 8]
dtype: object

Если вам нужен результат в виде списка, вызовите .tolist в конце:

output = pd.Series([list(np.array(x)[y]) for x, y in zip(ser1, ser2)]).tolist()
output
# [[1, 3], [], [7, 8]]

Вы также можете сделать это чистым списком Python для компоновки со вложенным списком.

pd.Series([
    [i for i, j in zip(x, y) if j] for x, y in zip(ser1, ser2)])

0    [1, 3]
1        []
2    [7, 8]
dtype: object

Я рекомендую это ДЛЯ МАЛЫХ СПИСКОВ , потому что преобразование списков в массивы (как сделанопервое решение) требует значительных накладных расходов.


Если вариант сглаживания ваших списков - вариант, вам следует подумать об этом, потому что это, вероятно, будет самым быстрым вариантом.

from itertools import chain

ser3 = np.array(list(chain.from_iterable(ser1)))
ser4 = np.array(list(chain.from_iterable(ser2)))

ser3[ser4]
# array([1, 3, 7, 8])

К сожалениюВы теряете структуру своего ввода, но если это не проблема, это победитель.

...