Pandas 如何筛选系列

Pandas How to filter a Series

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

name
383      3.000000
663      1.000000
726      1.000000
737      9.000000
833      8.166667

谁能告诉我如何过滤掉平均值为 1.000000 的行?谢谢你,非常感谢你的帮助。

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

另一种方法是先转换为 DataFrame 并使用 query 方法(假设您安装了 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")

从pandas version 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

作为 pandas 0.18.1 中的 , there are method-chaining improvements,可以很好地满足您的需求。

而不是使用 .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 支持类似的行为类。

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

天真的时机

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

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[]
  • []

这些接受可调用项 (lambdas) 应用于系列,而不是应用于这些系列中的个别

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

series_of_tuples.loc[lambda x: x.count('H')==1]

产生错误:

按键错误:'Level H must be same as name (None)'

一头雾水,好像用的是Series.count series_of_tuples.count(...) function,不是我想要的

我承认替代数据结构可能更好:

  • 类别数据类型?
  • 一个数据框(元组的每个元素成为一列)
  • 一系列字符串(只需将元组连接在一起):

这将创建一系列字符串(即通过连接元组;将元组中的字符连接到单个字符串上)

series_of_tuples.apply(''.join)

所以我可以使用 chainable Series.str.count

series_of_tuples.apply(''.join).str.count('H')==1