У меня есть такая серия после выполнения groupby ('name') и использования функции mean () в другом столбце
name
383 3.000000
663 1.000000
726 1.000000
737 9.000000
833 8.166667
Может ли кто-нибудь показать мне, как отфильтровать строки со средними значениями 1 000 000? Спасибо, и я очень ценю вашу помощь.
Ответы:
In [5]: import pandas as pd test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } s = pd.Series(test) s = s[s != 1] s Out[0]: 383 3.000000 737 9.000000 833 8.166667 dtype: float64
источник
s
а затем использовать его дважды в выражении). Хотя работает только с pandas 0.18.Из pandas версии 0.18+ фильтрацию серии также можно выполнить, как показано ниже
test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } pd.Series(test).where(lambda x : x!=1).dropna()
Оформить заказ: http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#method-chaininng-improvements
источник
Как отметил DACW , в pandas 0.18.1 есть улучшения в цепочке методов, которые очень хорошо делают то, что вы ищете.
Вместо использования
.where
вы можете передать свою функцию либо в.loc
индексатор, либо в индексатор серии[]
и избежать вызова.dropna
:test = pd.Series({ 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 }) test.loc[lambda x : x!=1] test[lambda x: x!=1]
Аналогичное поведение поддерживается в классах DataFrame и NDFrame.
источник
Быстрый способ сделать это - реконструировать, используя
numpy
для нарезки лежащих в основе массивов. Смотрите расписание ниже.mask = s.values != 1 pd.Series(s.values[mask], s.index[mask]) 0 383 3.000000 737 9.000000 833 8.166667 dtype: float64
наивное время
источник
Другой способ - сначала преобразовать в DataFrame и использовать метод запроса (при условии, что у вас установлен numexpr):
import pandas as pd test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } s = pd.Series(test) s.to_frame(name='x').query("x != 1")
источник
Если вам нравится связанная операция, вы также можете использовать
compress
функцию:test = pd.Series({ 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 }) test.compress(lambda x: x != 1) # 383 3.000000 # 737 9.000000 # 833 8.166667 # dtype: float64
источник
В моем случае у меня была серия панд, где значения представляют собой кортежи символов :
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.count
series_of_tuples.count(...)
, а это не то, что я хотел.Я допускаю, что альтернативная структура данных может быть лучше:
Это создает серию строк (т.е. путем объединения кортежа; объединения символов в кортеже в одну строку)
series_of_tuples.apply(''.join)
Тогда я могу использовать цепочку
Series.str.count
series_of_tuples.apply(''.join).str.count('H')==1
источник