Python 使用单独的数据帧选择数据帧的值
我有一个Python 使用单独的数据帧选择数据帧的值,python,numpy,pandas,Python,Numpy,Pandas,我有一个DataFrame,我想从中根据布尔标准从具有相同索引的单独DataFrame的每一行中选择一个唯一的值。下面的a是DataFrame我想选择一个值 发件人: 而b是我想用来索引事物的数据帧 In [2]: b Out[2]: 0 1 2 2015-05-22 15:00:00 False True False 2015-05-22 15:00:10 False False True 2015-05-
DataFrame
,我想从中根据布尔标准从具有相同索引的单独DataFrame
的每一行中选择一个唯一的值。下面的a
是DataFrame
我想选择一个值
发件人:
而b
是我想用来索引事物的数据帧
In [2]: b
Out[2]:
0 1 2
2015-05-22 15:00:00 False True False
2015-05-22 15:00:10 False False True
2015-05-22 15:00:20 True False False
2015-05-22 15:00:30 True False False
2015-05-22 15:00:40 True False False
索引很容易,但未选择的值都是NaN
s,但我想去掉这些值,只保留非空值
In [3]: d=a[b]
In [4]: d
Out[4]:
0 1 2
2015-05-22 15:00:00 NaN 0.791424 NaN
2015-05-22 15:00:10 NaN NaN -0.707294
2015-05-22 15:00:20 0.223438 NaN NaN
2015-05-22 15:00:30 -2.361507 NaN NaN
2015-05-22 15:00:40 0.400453 NaN NaN
我的kluge解决方案是将所有的NaN
s转换为0,然后对每行求和
In [5]: d[np.isnan(d)]=0
In [6]: d
Out[6]:
0 1 2
2015-05-22 15:00:00 0.000000 0.791424 0.000000
2015-05-22 15:00:10 0.000000 0.000000 -0.707294
2015-05-22 15:00:20 0.223438 0.000000 0.000000
2015-05-22 15:00:30 -2.361507 0.000000 0.000000
2015-05-22 15:00:40 0.400453 0.000000 0.000000
In [7]: e=d.sum(axis=1)
In [8]: e
Out[8]:
2015-05-22 15:00:00 0.791424
2015-05-22 15:00:10 -0.707294
2015-05-22 15:00:20 0.223438
2015-05-22 15:00:30 -2.361507
2015-05-22 15:00:40 0.400453
Freq: 10S, dtype: float64
有没有一种方法可以通过索引来实现这一点。我尝试了多种方法,但没有找到好的或更好的解决方案。一种方法是叠加结果:
d = a[b].stack()
默认设置将删除空值。这将在索引中为您提供第二个可能不需要的级别。如果不行,就把它扔了。仅当每行中有一个True
时,沿轴=1求和才会起作用,但情况并非总是如此 你不需要d[np.isnan(d)]=0
,你可以直接做d.sum(axis=1)
,这可以归结为像a[b].sum(axis=1)
这样的单行,所以问题实际上可以归结为如何获得给定行中True
列的索引位置。我怀疑你这样做的方式(由@JohnGalt改进)这是一种很好的方法,因为您从一个掩码(数据帧)开始。任何其他解决方案都需要将[False-False-True]
转换为2
,然后将其插入iloc
。但我不认为这比你已经在做的事情有什么好处。现在,如果你不是真的从那个面具开始,那么可能有一个更好的方法。@JohnGalt的方法非常适合我。哦,有趣的是,你可以用stack来做。看起来很好,虽然我不清楚它比a[b]好还是坏。如上所述,sum(axis=1)
。是的,我只是认为它可能会在稍微不同的情况下有所帮助,因为每行中没有一个True
。此外,我认为问题本质上是将多个列转换为一个列,我认为这自然属于pivot和stack等领域。对我来说,对空值求和的直观性要差一些。此外,保留每行中的非空值来自哪个列的信息可能会很有意义。另一方面,堆栈似乎要慢2-3倍左右
d = a[b].stack()