Python 熊猫如何过滤一系列

Python 熊猫如何过滤一系列,python,pandas,Python,Pandas,在执行groupby('name')并在另一列上使用mean()函数之后,我有一个类似这样的系列 name 383 3.000000 663 1.000000 726 1.000000 737 9.000000 833 8.166667 有人能告诉我如何过滤出平均值为1.000000的行吗?谢谢您,我非常感谢您的帮助。另一种方法是首先转换为数据帧并使用该方法(假设您已安装numexpr): In [5]: import pandas as p

在执行groupby('name')并在另一列上使用mean()函数之后,我有一个类似这样的系列

name
383      3.000000
663      1.000000
726      1.000000
737      9.000000
833      8.166667

有人能告诉我如何过滤出平均值为1.000000的行吗?谢谢您,我非常感谢您的帮助。

另一种方法是首先转换为数据帧并使用该方法(假设您已安装numexpr):

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

从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()
结帐:

正如pandas 0.18.1所述,它能很好地满足您的需求

您可以将函数传递给
.loc
索引器或序列索引器
[]
,而不是使用
.where
,并避免调用
.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类也支持类似的行为

如果您喜欢链式操作,还可以使用
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

实现这一点的一种快速方法是使用
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
天真的时机

在我的例子中,我有一个panda系列,其中的值是字符的元组:

因此,我可以使用索引来过滤序列,但要创建所需的索引,我需要
apply
。我的条件是“找到所有正好有一个“H”的元组”

我承认它不是“可链接的”(也就是说,请注意,我重复了两次
series\u of tuples
;您必须将任何临时序列存储到变量中,以便可以对其调用apply(…)

可能还有其他方法(除了
.apply(…)
)可以按元素操作以生成布尔索引

使用可链接函数的许多其他答案(包括已接受的答案),如:

  • .compress()
  • .where()
  • .loc[]
  • []
这些函数接受应用于序列的可调用函数(lambda),而不是应用于这些序列中的单个值

因此,当我尝试将上述条件/callable/lambda与任何可链接函数(如
.loc[]
)一起使用时,我的一系列元组表现得很奇怪:

series_of_tuples.loc[lambda x: x.count('H')==1]
产生错误:

KeyError:“级别H必须与名称相同(无)”

我很困惑,但它似乎在使用,这不是我想要的

我承认另一种数据结构可能更好:

  • 类别数据类型
  • 数据帧(元组的每个元素成为一列)
  • 一系列字符串(仅将元组连接在一起):
这将创建一系列字符串(即通过连接元组;将元组中的字符连接到单个字符串上)

这样我就可以使用


那么,如何根据给定的条件筛选一个序列呢?我更喜欢下面的答案,因为它们可以链接(即不需要定义
s
,然后在表达式中使用它两次)。虽然只适用于pandas 0.18。也可以在piRSquared中查看计时比较。这是我最喜欢的答案,而且它似乎是不使用numpy的情况下最快的(请参见计时比较)。我喜欢你的方法,我想知道如果我有多个面具会怎么样。Thx@MenglongLi看情况,你应该问一个问题。很可能,您会将它们与&。mask=mask1&mask2在方法链接方面非常好(让我想起了Spark)。这是真的,但是Spark在这种情况下做了一些更直观的事情:它只是去除了与谓词不匹配的行,这意味着在我阅读文档之前不使用“.dropna()”部分,这对我来说显然是多余的。我不认为将条件作为字符串传递是一个好主意。这会增加数据帧的所有开销,而且速度会非常慢。请注意
pandas.Series.compress
自0.24.0版以来就不推荐使用。熊猫的。
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)
series_of_tuples[series_of_tuples.apply(lambda x: x.count('H')==1)]
series_of_tuples.loc[lambda x: x.count('H')==1]
series_of_tuples.apply(''.join)
series_of_tuples.apply(''.join).str.count('H')==1