В моем случае у меня была серия панд, где значения представляют собой кортежи символов :
Out[67]
0 (H, H, H, H)
1 (H, H, H, T)
2 (H, H, T, H)
3 (H, H, T, T)
4 (H, T, H, H)
Поэтому я мог бы использовать индексирование для фильтрации ряда, но для создания нужного мне индекса apply
. Мое условие - «найти все кортежи, в которых есть ровно одна буква« H »».
series_of_tuples[series_of_tuples.apply(lambda x: x.count('H')==1)]
Я допускаю, что это не "цепочка" (т.е. обратите внимание, что я повторяю series_of_tuples
дважды; вы должны сохранить любую временную серию в переменной, чтобы вы могли вызвать для нее apply (...)).
Также могут быть другие методы (помимо .apply(...)
), которые могут работать поэлементно для создания логического индекса.
Многие другие ответы (включая принятый ответ) с использованием цепных функций, таких как:
.compress()
.where()
.loc[]
[]
Они принимают вызовы (лямбды), которые применяются к серии , а не к отдельным значениям в этой серии!
Поэтому моя серия кортежей вела себя странно, когда я пытался использовать указанное выше условие / callable / lambda с любой из цепных функций, например .loc[]
:
series_of_tuples.loc[lambda x: x.count('H')==1]
Выдает ошибку:
KeyError: "Уровень H должен совпадать с именем (None)"
Я был очень сбит с толку, но похоже, что он использует функцию Series.countseries_of_tuples.count(...)
, а это не то, что я хотел.
Я допускаю, что альтернативная структура данных может быть лучше:
- Тип данных категории?
- Dataframe (каждый элемент кортежа становится столбцом)
- Серия строк (просто объедините кортежи вместе):
Это создает серию строк (т.е. путем объединения кортежа; объединения символов в кортеже в одну строку)
series_of_tuples.apply(''.join)
Тогда я могу использовать цепочкуSeries.str.count
series_of_tuples.apply(''.join).str.count('H')==1