Python 带命名索引的布尔子集
我尝试使用布尔数组来子集数据帧。这项工作:Python 带命名索引的布尔子集,python,python-3.x,pandas,boolean,Python,Python 3.x,Pandas,Boolean,我尝试使用布尔数组来子集数据帧。这项工作: df = pd.DataFrame( [ (0, 0, 1), (0, 1, 2), (0, 3, 20), (1, 0, 2), (1, 1, 1), (1, 2, 30), ], columns = ['s', 'j', 'q'] ) df[df['j'] == 0] df.loc[df['j'] == 0] df.set_i
df = pd.DataFrame(
[
(0, 0, 1),
(0, 1, 2),
(0, 3, 20),
(1, 0, 2),
(1, 1, 1),
(1, 2, 30),
],
columns = ['s', 'j', 'q']
)
df[df['j'] == 0]
df.loc[df['j'] == 0]
df.set_index('s')[df.set_index('s')['j'] == 0]
df.set_index('s').loc[df.set_index('s')['j'] == 0]
然而,以下几点失败了:
df.set_index('s')[df['j'] == 0]
df.set_index('s').loc[df['j'] == 0]
我得到的每个实例weheres
都等于0,而不是j
。我求助于查询(我的条件比字面上的j==0更复杂,或者我会直接使用它):
有没有一种不创建临时变量的方法?非常感谢!Python 3.7和0.23.4
编辑
我所做的事情的问题是,布尔级数和数据帧有不同的索引。下面的答案详细介绍了几种解决方法,但我支持这两种方法之一:
df.set_index('s')[(df['j'] == 0).values]
或
不要在布尔运算之间重新设置索引。您的布尔序列基于原始索引来放置真值和假值,因此不能在具有不同索引的数据帧上重复使用该序列,因为这些索引随后通过该新索引映射到不同的行
如果必须创建具有不同索引的数据帧,请在创建后创建布尔数组,或在具有相同索引的另一个数据帧上创建布尔数组。所以这是可行的:
df = pd.DataFrame(
[
(0, 0, 1),
(0, 1, 2),
(0, 3, 20),
(1, 0, 2),
(1, 1, 1),
(1, 2, 30),
],
columns = ['s', 'j', 'q']
)
df[df['j'] == 0]
df.loc[df['j'] == 0]
df.set_index('s')[df.set_index('s')['j'] == 0]
df.set_index('s').loc[df.set_index('s')['j'] == 0]
同样
df_indexed_on_s = df.set_index('s')
df_indexed_on_s[df_indexed_on_s['j'] == 0]
df_indexed_on_s.loc[df_indexed_on_s['j'] == 0]
如果必须以内联方式执行此操作,可能需要使用可调用索引;传递给[…]
索引操作的函数应返回布尔序列,因此您也可以使用该序列:
df.set_index('s')[lambda sdf: sdf['j'] == 0]
df.set_index('s').loc[lambda sdf: sdf['j'] == 0]
或者,您可以使用Pandas对数据帧对表示为字符串的查询求值:
df.set_index('s').query('j == 0')
在引擎盖下,对附加到df.set_index('s')
的索引进行迭代,并将该索引中的值与df['j']==0
系列的值进行检查,以查看应选择哪些行。后一个系列仍然使用原始索引(数字为0-6的RangeIndex
),因此将数字0-6映射到True
和False
值,而s
只有一个Int64Index
索引,其值为0
和1
。对于s
索引具有0
的行,(df['j']==0)[0]
结果为True
,因此选择这些行,而对于1
结果为False
df_indexed_on_s[df_indexed_on_s['j']==0]
的布尔索引需要更多的工作,因为那里的索引是相同的基于s
的Int64Index,并且
0`映射到3个单独的布尔结果,因此熊猫知道使用比索引更多的内容来选择匹配行。不要在布尔操作之间重新设置索引。您的布尔序列基于原始索引来放置真值和假值,因此不能在具有不同索引的数据帧上重复使用该序列,因为这些索引随后通过该新索引映射到不同的行
如果必须创建具有不同索引的数据帧,请在创建后创建布尔数组,或在具有相同索引的另一个数据帧上创建布尔数组。所以这是可行的:
df = pd.DataFrame(
[
(0, 0, 1),
(0, 1, 2),
(0, 3, 20),
(1, 0, 2),
(1, 1, 1),
(1, 2, 30),
],
columns = ['s', 'j', 'q']
)
df[df['j'] == 0]
df.loc[df['j'] == 0]
df.set_index('s')[df.set_index('s')['j'] == 0]
df.set_index('s').loc[df.set_index('s')['j'] == 0]
同样
df_indexed_on_s = df.set_index('s')
df_indexed_on_s[df_indexed_on_s['j'] == 0]
df_indexed_on_s.loc[df_indexed_on_s['j'] == 0]
如果必须以内联方式执行此操作,可能需要使用可调用索引;传递给[…]
索引操作的函数应返回布尔序列,因此您也可以使用该序列:
df.set_index('s')[lambda sdf: sdf['j'] == 0]
df.set_index('s').loc[lambda sdf: sdf['j'] == 0]
或者,您可以使用Pandas对数据帧对表示为字符串的查询求值:
df.set_index('s').query('j == 0')
在引擎盖下,对附加到df.set_index('s')
的索引进行迭代,并将该索引中的值与df['j']==0
系列的值进行检查,以查看应选择哪些行。后一个系列仍然使用原始索引(数字为0-6的RangeIndex
),因此将数字0-6映射到True
和False
值,而s
只有一个Int64Index
索引,其值为0
和1
。对于s
索引具有0
的行,(df['j']==0)[0]
结果为True
,因此选择这些行,而对于1
结果为False
df_indexed_on_s[df_indexed_on_s['j']==0]
的布尔索引需要更多的工作,因为那里的索引是相同的基于s
-的Int64Index,并且
0`映射到3个单独的布尔结果,因此熊猫知道使用比索引更多的方法来选择匹配行。df.set_index('s')
的目的是什么?您当前的解决方案似乎不使用s
作为索引,也不需要它。@正如大多数人可能猜到的那样,我的代码在无明显原因地对数据进行子设置后不会结束。df.set\u index('s')
的目的是什么?您当前的解决方案似乎不使用s
作为索引,也不需要它。@正如大多数人可能猜到的那样,我的代码在无明显原因地对数据进行子设置后不会结束……这些还支持可调用项:df.set_index('s')[lambda df:df['j']==0]
@ayhan:在哪一点上,当前数据帧被传递给lambda参数,是的。我还要指出版本df.set_index('s').query('j==0')
,它可以满足许多简单的索引需求。它不需要构造一个明确的序列(使用顶级的pd.eval
)。既然.set\u index
不会修改顺序,那么如何与底层的ndarray
对齐呢df.set_index('s')[(df.j==0).values]
?@ALollz:更可能的是,传入numpy布尔数组是另一种选择。但是我认为我们应该停止列出更多的选项。这些选项也支持可调用项:df.set_index('s')[lambda-df:df['j']==0]
@ayhan:是的,当前的数据帧在哪一点上被传递给lambda参数。我还需要指出版本df.set_index('s')。query('j==0')
,这将满足许多简单的索引需求。它不需要构造显式序列(使用顶级的pd.eval
)。如何与底层的ndarray
对齐,因为.set