In [167]: n = 10
In [168]: df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc'))
In [169]: df
Out[169]:
a b c
0 0.687704 0.582314 0.281645
1 0.250846 0.610021 0.420121
2 0.624328 0.401816 0.932146
3 0.011763 0.022921 0.244186
4 0.590198 0.325680 0.890392
5 0.598892 0.296424 0.007312
6 0.634625 0.803069 0.123872
7 0.924168 0.325076 0.303746
8 0.116822 0.364564 0.454607
9 0.986142 0.751953 0.561512
# pure python
In [170]: df[(df.a < df.b) & (df.b < df.c)]
Out[170]:
a b c
3 0.011763 0.022921 0.244186
8 0.116822 0.364564 0.454607
# query
In [171]: df.query('(a < b) & (b < c)')
Out[171]:
a b c
3 0.011763 0.022921 0.244186
8 0.116822 0.364564 0.454607
您还可以通过添加 @ 来访问环境中的变量 .
exclude = ('red', 'orange')
df.query('color not in @exclude')
2076
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split(),
'C': np.arange(8), 'D': np.arange(8) * 2})
df[df['A']=='foo']
OUTPUT:
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
In [76]: df.iloc[np.where(df.A.values=='foo')]
Out[76]:
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
时间比较:
In [68]: %timeit df.iloc[np.where(df.A.values=='foo')] # fastest
1000 loops, best of 3: 380 µs per loop
In [69]: %timeit df.loc[df['A'] == 'foo']
1000 loops, best of 3: 745 µs per loop
In [71]: %timeit df.loc[df['A'].isin(['foo'])]
1000 loops, best of 3: 562 µs per loop
In [72]: %timeit df[df.A=='foo']
1000 loops, best of 3: 796 µs per loop
In [74]: %timeit df.query('(A=="foo")') # slowest
1000 loops, best of 3: 1.71 ms per loop
5
对于pandas中的给定值,仅选择多列中的特定列:
select col_name1, col_name2 from table where column_name = some_value.
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split(),
'C': np.arange(8), 'D': np.arange(8) * 2})
print(df)
# A B C D
# 0 foo one 0 0
# 1 bar one 1 2
# 2 foo two 2 4
# 3 bar three 3 6
# 4 foo two 4 8
# 5 bar two 5 10
# 6 foo one 6 12
# 7 foo three 7 14
print(df.loc[df['A'] == 'foo'])
产量
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
如果您想要包含多个值,请将它们放在列表中(或者更常见的是,任何可迭代的值)并使用 isin :
print(df.loc[df['B'].isin(['one','three'])])
产量
A B C D
0 foo one 0 0
1 bar one 1 2
3 bar three 3 6
6 foo one 6 12
7 foo three 7 14
但请注意,如果您希望多次执行此操作,则首先创建索引更有效,然后使用 df.loc :
df = df.set_index(['B'])
print(df.loc['one'])
产量
A C D
B
one foo 0 0
one bar 1 2
one foo 6 12
或者,要包含索引中的多个值,请使用 df.index.isin :
df.loc[df.index.isin(['one','two'])]
产量
A C D
B
one foo 0 0
one bar 1 2
two foo 2 4
two foo 4 8
two bar 5 10
one foo 6 12
import pandas as pd, numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split(),
'C': np.arange(8), 'D': np.arange(8) * 2})
for j in spec.columns:
d = pd.concat([df] * j, ignore_index=True)
for i in spec.index:
stmt = '{}(d)'.format(i)
setp = 'from __main__ import d, {}'.format(i)
spec.at[i, j] = timeit(stmt, setp, number=50)
9
tl;博士
大熊猫相当于
select * from table where column_name = some_value
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split(),
'C': np.arange(8), 'D': np.arange(8) * 2})
print(df)
# A B C D
# 0 foo one 0 0
# 1 bar one 1 2
# 2 foo two 2 4
# 3 bar three 3 6
# 4 foo two 4 8
# 5 bar two 5 10
# 6 foo one 6 12
# 7 foo three 7 14
print(df.loc[df['A'] == 'foo'])
产量
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
如果您要选择多个条件,可以将它们放在列表中并使用“isin”:
print(df.loc[df['B'].isin(['one','three'])])
产量
A B C D
0 foo one 0 0
1 bar one 1 2
3 bar three 3 6
6 foo one 6 12
7 foo three 7 14
但请注意,如果您希望多次执行此操作,首先将A作为索引更有效,然后使用df.loc:
df = df.set_index(['A'])
print(df.loc['foo'])
产量
A B C D
foo one 0 0
foo two 2 4
foo two 4 8
foo one 6 12
foo three 7 14
import pandas as pd
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split()})
print("Original dataframe:")
print(df)
b_is_two_dataframe = pd.DataFrame(df.groupby('B').get_group('two').reset_index()).drop('index', axis = 1)
#NOTE: the final drop is to remove the extra index column returned by groupby object
print('Sub dataframe where B is two:')
print(b_is_two_dataframe)
运行此给出:
Original dataframe:
A B
0 foo one
1 bar one
2 foo two
3 bar three
4 foo two
5 bar two
6 foo one
7 foo three
Sub dataframe where B is two:
A B
0 foo two
1 foo two
2 bar two
13 回答
如果您根据列中的某个整数查找行,那么
如果您要根据字符串查找值
如果基于两者
我发现以前答案的语法是多余的,难以记住 . Pandas在v0.13中介绍了
query()
方法,我更喜欢它 . 对于你的问题,你可以做df.query('col == val')
转载自http://pandas.pydata.org/pandas-docs/version/0.17.0/indexing.html#indexing-query
您还可以通过添加
@
来访问环境中的变量 .你也可以使用.apply:
它实际上是按行工作的(即,将函数应用于每一行) .
输出是
结果与@unutbu提到的结果相同
使用numpy.where可以实现更快的结果 .
例如,使用unubtu's setup -
时间比较:
对于pandas中的给定值,仅选择多列中的特定列:
选项:
要么
要选择列值等于标量的行
some_value
,请使用==
:要选择列值在可迭代的
some_values
中的行,请使用isin
:将多个条件与
&
组合:要选择列值不等于
some_value
的行,请使用!=
:isin
返回一个布尔系列,因此要选择其值不在some_values
中的行,请使用~
否定布尔系列:例如,
产量
如果您想要包含多个值,请将它们放在列表中(或者更常见的是,任何可迭代的值)并使用
isin
:产量
但请注意,如果您希望多次执行此操作,则首先创建索引更有效,然后使用
df.loc
:产量
或者,要包含索引中的多个值,请使用
df.index.isin
:产量
有一些从pandas数据框中选择行的基本方法 .
布尔索引
位置索引
标签索引
API
对于每种基类型,我们可以通过将自己限制在pandas API中来保持简单,或者我们可以在API之外冒险,通常进入
numpy
,并加快速度 .我将向您展示每个示例,并指导您何时使用某些技术 .
Setup
我们需要的第一件事是确定一个条件,作为我们选择行的标准 . OP提供了
column_name == some_value
. 我们将从那里开始并包含一些其他常见用例 .借用@unutbu:
假设我们的标准是列
'A'
='foo'
1.
布尔索引要求查找每行的
'A'
列的真值等于'foo'
,然后使用这些真值来标识要保留的行 . 通常,我们将此系列命名为一个真值数组mask
. 我们也会在这里这样做 .然后,我们可以使用此掩码对数据帧进行切片或索引
这是完成此任务的最简单方法之一,如果性能或直观性不是问题,那么这应该是您选择的方法 . 但是,如果考虑性能,那么您可能需要考虑另一种创建
mask
的方法 .2.
位置索引有其用例,但这不是其中之一 . 为了确定切片的位置,我们首先需要执行上面我们所做的相同的布尔分析 . 这使我们执行一个额外的步骤来完成相同的任务 .
3.
标签索引可以非常方便,但在这种情况下,我们再次做更多的工作,没有任何好处
4.
pd.DataFrame.query
是一种非常优雅/直观的方式来执行此任务 . 但往往比较慢 . However ,如果你注意下面的时间,对于大数据,查询效率很高 . 比标准方法更重要,与我最好的建议相似 .我的偏好是使用
Boolean
mask
可以通过修改我们创建
Boolean
mask
的方式来实现实际改进 .mask alternative 1
使用底层
numpy
数组并放弃创建另一个pd.Series
的开销我将在最后展示更完整的时间测试,但只是看看我们使用示例数据帧获得的性能提升 . 首先我们来看看创建
mask
的区别使用
numpy
数组评估mask
的速度要快30倍 . 这部分是由于numpy
评估通常更快 . 部分原因还在于缺少构建索引和相应的pd.Series
对象所需的开销 .接下来我们来看看时间用一个
mask
与另一个切片 .性能提升并不明显 . 我们将看看这是否适用于更强大的测试 .
mask alternative 2
我们也可以重建数据帧 . 在重建数据帧时有一个很大的警告 - 你必须在这样做的时候处理
dtypes
!而不是
df[mask]
,我们将这样做如果数据帧是混合类型,我们的示例是,那么当我们得到
df.values
时,结果数组是dtype
object
,因此,新数据帧的所有列都将是dtype
object
. 因此需要astype(df.dtypes)
并消除任何潜在的性能提升 .但是,如果数据帧不是混合类型,则这是一种非常有用的方法 .
特定
与
我们把时间缩短了一半 .
mask alternative 3
@unutbu还向我们展示了如何使用
pd.Series.isin
来计算df['A']
在一组值中的每个元素 . 如果我们的值集是一个值的集合,即'foo'
,则计算结果相同 . 但如果需要,它还可以推广包括更大的值集 . 事实证明,即使这是一个更通用的解决方案,这仍然非常快 . 对于那些不熟悉这个概念的人来说,唯一真正的损失是直观的 .但是,和以前一样,我们可以利用
numpy
来提高性能,同时几乎不牺牲任何东西 . 我们将使用np.in1d
Timing
我将包括其他帖子中提到的其他概念以供参考 .
代码如下
此表中的每个列表示一个不同长度的数据帧,我们在其上测试每个函数 . 每列显示相对时间,最快的函数给定
1.0
的基本索引 .您会注意到
mask_with_values
和mask_with_in1d
之间似乎共享最快的时间Functions
Testing
Special Timing
查看我们在整个数据帧中只有一个非对象
dtype
时的特殊情况 . 代码如下事实证明,重建不值得过去几百行 .
Functions
Testing
tl;博士
大熊猫相当于
是
多个条件:
要么
代码示例
在上面的代码中,行
df[df.foo == 222]
在这种情况下根据列值222
给出行 .多种条件也是可能的:
但是在那时我建议使用query函数,因为它不那么冗长并产生相同的结果:
如果你来到这里寻找从数据框中选择行,包括那些列的值不是任何值列表的行,这里是如何翻转unutbu的答案以获取上面的值列表:
(当然,为了不包含单个值,您只需使用常规非等于运算符
!=
. )例:
给我们
要仅在
B
列中的那些行one
或three
的子集:产量
这是一个简单的例子
我只是尝试编辑这个,但我没有登录,所以我不确定我的编辑去了哪里 . 我试图纳入多个选择 . 所以我认为更好的答案是:
对于单个值,最直接(人类可读)可能是:
对于值列表,您还可以使用:
例如,
产量
如果您要选择多个条件,可以将它们放在列表中并使用“isin”:
产量
但请注意,如果您希望多次执行此操作,首先将A作为索引更有效,然后使用df.loc:
产量
要附加到这个着名的问题(虽然有点太晚):您也可以使用
df.groupby('column_name').get_group('column_desired_value').reset_index()
来创建具有特定值的指定列的新数据帧 . 例如 .运行此给出: