To select rows whose column value equals a scalar, some_value, use ==:
df.loc[df['column_name'] == some_value]
To select rows whose column value is in an iterable, some_values, use isin:
df.loc[df['column_name'].isin(some_values)]
Combine multiple conditions with &:
df.loc[(df['column_name'] >= A) & (df['column_name'] <= B)]
Note the parentheses. Due to Python's operator precedence rules, & binds more tightly than <= and >=. Thus, the parentheses in the last example are necessary. Without the parentheses
To select rows whose column value does not equalsome_value, use !=:
df.loc[df['column_name'] != some_value]
isin returns a boolean Series, so to select rows whose value is not in some_values, negate the boolean Series using ~:
df.loc[~df['column_name'].isin(some_values)]
For example,
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'])
yields
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
If you have multiple values you want to include, put them in a list (or more generally, any iterable) and use isin:
print(df.loc[df['B'].isin(['one','three'])])
yields
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
Note, however, that if you wish to do this many times, it is more efficient to make an index first, and then use df.loc:
df = df.set_index(['B'])
print(df.loc['one'])
yields
A C D
B
one foo 0 0
one bar 1 2
one foo 6 12
or, to include multiple values from the index use df.index.isin:
df.loc[df.index.isin(['one','two'])]
yields
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)
pandas.notna(df["colume_name"]) == True # Not NaN
df['colume_name'].str.contains("text") # Search for "text"
df['colume_name'].str.lower().str.contains("text") # Search for "text", after converting to lowercase
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
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
s=datetime.datetime.now()
my_dict={}
for i, my_key in enumerate(df['some_column'].values):
if i%100==0:
print(i) # to see the progress
if my_key not in my_dict.keys():
my_dict[my_key]={}
my_dict[my_key]['values']=[df.iloc[i]['another_column']]
else:
my_dict[my_key]['values'].append(df.iloc[i]['another_column'])
e=datetime.datetime.now()
print('operation took '+str(e-s)+' seconds')```
16条答案
按热度按时间oprakyz71#
To select rows whose column value equals a scalar,
some_value
, use==
:To select rows whose column value is in an iterable,
some_values
, useisin
:Combine multiple conditions with
&
:Note the parentheses. Due to Python's operator precedence rules,
&
binds more tightly than<=
and>=
. Thus, the parentheses in the last example are necessary. Without the parenthesesis parsed as
which results in a Truth value of a Series is ambiguous error.
To select rows whose column value does not equal
some_value
, use!=
:isin
returns a boolean Series, so to select rows whose value is not insome_values
, negate the boolean Series using~
:For example,
yields
If you have multiple values you want to include, put them in a list (or more generally, any iterable) and use
isin
:yields
Note, however, that if you wish to do this many times, it is more efficient to make an index first, and then use
df.loc
:yields
or, to include multiple values from the index use
df.index.isin
:yields
e5nqia272#
有几种方法可以从Pandas Dataframe 中选择行:
1.布尔索引(
df[df['col'] == value
])1.位置索引(
df.iloc[...]
)1.标签索引(
df.xs(...)
)1.
df.query(...)
接口下面我将向您展示每种技术的示例,并给出何时使用某些技术的建议。假设我们的标准是列
'A'
=='foo'
(关于性能的注意:对于每个基本类型,我们可以通过使用Pandas API来使事情变得简单,或者我们可以在API之外冒险,通常是进入NumPy,并加快速度。)
设置
我们需要做的第一件事是确定一个条件,该条件将作为我们选择行的标准。我们将从OP的案例
column_name == some_value
开始,并包括其他一些常见用例。从@unutbu借用:
1.布尔索引
..。布尔索引需要找到每一行的
'A'
列的真值等于'foo'
,然后使用这些真值来确定要保留哪些行。通常,我们会将这个序列命名为真值数组mask
。我们在这里也会这样做。然后,我们可以使用此掩码对 Dataframe 进行切片或索引
这是完成这项任务最简单的方法之一,如果性能或直觉性不是问题,这应该是你选择的方法。但是,如果性能是个问题,那么您可能需要考虑另一种创建
mask
的方法。2.位置索引
位置索引(
df.iloc[...]
)有其用例,但这不是其中之一。为了确定在哪里切片,我们首先需要执行与上面相同的布尔分析。这就让我们多做了一步来完成同样的任务。3.标签标引
4.
df.query()
接口pd.DataFrame.query
*是执行此任务的一种非常优雅/直观的方式,但通常速度较慢。然而,如果您注意下面的计时,对于大数据,查询效率非常高。这比标准方法更有说服力,与我的最佳建议差不多。我更喜欢使用
Boolean``mask
实际的改进可以通过修改我们创建
Boolean``mask
的方式来实现。**
mask
备选方案1使用底层NumPy数组,并放弃创建另一个pd.Series
的开销我将在最后展示更多完整的时间测试,但只看一下我们使用样例数据框获得的性能收益。首先,我们看看创建
mask
的不同之处使用NumPy数组评估
mask
的速度大约快30倍。这在一定程度上是因为NumPy计算通常更快。这在一定程度上也是因为缺乏构建索引和相应的pd.Series
对象所需的开销。接下来,我们将查看
mask
与mask
的切片时间。性能提升并不是那么明显。我们将拭目以待,看看这是否经得起更强大的测试。
mask
备选方案2我们也可以重建 Dataframe 。在重建 Dataframe 时有一个很大的警告-您必须在执行此操作时注意dtypes
!我们将这样做,而不是
df[mask]
如果 Dataframe 是混合类型(我们的示例是混合类型),则当我们获得
df.values
时,结果数组是dtype``object
,因此,新 Dataframe 的所有列都将是dtype``object
。因此需要astype(df.dtypes)
并扼杀任何潜在的性能提升。但是,如果数据框不是混合类型,这是一种非常有用的方法。
vt.给出
对战
我们把时间缩短了一半。
mask
备选方案3@unutbu还向我们展示了如何使用
pd.Series.isin
来说明df['A']
中的每个元素都在一组值中。如果我们的值集是一个值集,即'foo'
,则计算结果相同。但如果需要,它还可以泛化为包含更大的值集。事实证明,这仍然是相当快的,尽管这是一个更一般的解决方案。对于那些不熟悉这个概念的人来说,唯一真正的损失是直觉。然而,和以前一样,我们可以利用NumPy来提高性能,而几乎不会牺牲任何东西。我们将使用
np.in1d
计时
我会将其他帖子中提到的其他概念也包括在内,以供参考。
以下代码
此表中的每个列代表一个不同长度的 Dataframe ,我们在该 Dataframe 上测试每个函数。每一列都显示了所用的相对时间,其中最快的函数的基本索引为
1.0
。您会注意到,最快的时间似乎在
mask_with_values
和mask_with_in1d
之间共享。函数
测试
特殊计时
看一下当我们对整个 Dataframe 具有单个非对象
dtype
时的特殊情况。以下代码
事实证明,经过几百行重建是不值得的。
函数
测试
tjvv9vkg3#
tl;DR
Pandas相当于
是
多个条件:
或
代码示例
在上面的代码中,
df[df.foo == 222]
行根据列值提供行,在本例中为222
。还可能出现多种情况:
但在这一点上,我建议使用query函数,因为它不那么冗长,并产生相同的结果:
jfewjypa4#
我发现前面答案的语法是多余的,很难记住。Pandas在v0.13中引入了
query()
方法,我更喜欢它。对于你的问题,你可以做df.query('col == val')
。转载自Query()方法(实验性):
您还可以通过添加
@
来访问环境中的变量。r6vfmomb5#
Pandas>=0.25.0使用
.query
更灵活:由于PANDA>=0.25.0,我们可以使用
query
方法来过滤 Dataframe ,其中包含PANDA方法,甚至是包含空格的列名。通常,列名中的空格会产生错误,但现在我们可以使用反号(`)来解决这个问题-请参阅GitHub:将
.query
用于方法str.endswith
:输出
此外,我们还可以在查询中使用局部变量,方法是在其前面加上
@
:输出
euoag5mw6#
用于仅从Pandas中给定值的多列中选择特定列:
选项
loc
:或
query
:qq24tv8q7#
在较新版本的Pandas中,灵感来自文档(查看数据):
通过将子句放在括号
()
中并与&
和|
(和/或)组合来组合多个条件。就像这样:其他过滤器
wpcxdonn8#
使用numpy.where可以更快地实现结果。
例如,通过UNUBTU的设置-
时序比较:
35g0bw719#
下面是一个简单的例子
ivqmmu1c10#
添加:您还可以执行
df.groupby('column_name').get_group('column_desired_value').reset_index()
来创建具有特定值的指定列的新数据框。例如,运行此程序可实现以下效果:
5vf7fwbs11#
您还可以使用.Apply:
它实际上是按行工作的(即,将函数应用于每一行)。
输出为
结果与@unutbu提到的使用相同
w51jfk4q12#
如果你想反复查询你的 Dataframe ,速度对你来说很重要,最好的办法是把你的 Dataframe 转换成字典,然后这样做可以使查询速度提高数千倍。
在创建我的词典之后,您可以完成以下操作:
如果在COLUMN_NAME中有重复的值,则不能创建字典。但您可以使用:
yqkkidmi13#
DataFrame上使用DuckDB选择行的SQL语句
使用DuckDB,我们可以在highly performant way中使用SQL语句查询PandasDataFrame。
由于问题是如何根据列值从DataFrame中选择行?,而问题中的示例是一个SQL查询,因此这个答案在本主题中看起来很合乎逻辑。
示例:
dgiusagp14#
您可以将
loc
(方括号)与函数一起使用:产出:
或
产出:
此方法的优点是您可以将选择与以前的操作链接起来。例如:
VS
产出:
hujrc8aj15#
很好的答案。只是,当Dataframe 大小接近百万行时,许多方法在使用
df[df['col']==val]
时往往需要很长时间。我想让所有可能的值“Another_Column”对应于“SOME_COLUMN”中的特定值(在本例中是在字典中)。这起作用了,而且很快。