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
在执行 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 中的
而不是使用 .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