查找假真的和真真的行索引

1 投票
3 回答
512 浏览
提问于 2025-04-18 13:33

我有一个名为 data['3_changed'] 的布尔向量,它是从一个 pandas 数据框中提取的。要找到所有标记为 True 的值的索引,我只需要输入:

In [106]: np.where(data['3_changed'])
Out[106]: (array([    37,     41,     83, ..., 998011, 998019, 998025]),)

现在我想要做的是:

  1. 访问每个 True 值之前的那一行
  2. 如果那一行的值是 False,也获取那一行的索引

我尝试过:

np.where(data['3_changed'].diff())

但是,这个方法返回的是有 False-True 组合的行,而排除了 True-True 的行。例如,行 997932 和 997933 就会被排除在外。

997928    False
997929    False
997930    False
997931    False
997932     True
997933     True
997934    False
997935    False
997936    False
997937    False
997938    False
997939    False
997940    False
997941    False
997942     True

有没有什么办法可以高效地遍历我的数据框 data,并用某种 if 语句来进行这个检查呢?

3 个回答

0

使用 shift(distance) 这个方法,你可以比较两行数据:

data = '''idx  a
997928    False
997929    False
997930    False
997931    False
997932     True
997933     True
997934    False
997935    False
997936    False
997937    False
997938    False
997939    False
997940    False
997941    False
997942     True'''

import pandas as pd
from StringIO import StringIO

df = pd.DataFrame.from_csv( StringIO(data), sep='\s+' )

#df['b'] = df['a'].shift(-1)

print df

print df[ (df['a'] == False) & (df['a'].shift(-1) == True) ]

结果

            a
idx          
997931  False
997941  False

然后你可以用 .index 来只获取 indexes(索引)

print df[ (df['a'] == False) & (df['a'].shift(-1) == True) ].index

顺便提一下:你可以加上 df['b'] = df['a'].shift(-1) 来查看被比较的值

            a      b
idx                 
997928  False  False
997929  False  False
997930  False  False
997931  False   True
997932   True   True
997933   True  False
997934  False  False
997935  False  False
997936  False  False
997937  False  False
997938  False  False
997939  False  False
997940  False  False
997941  False   True
997942   True    NaN
0

如果你的布尔数组叫做 a,你可以使用

a | numpy.r_[a[1:], False]

来得到一个新的数组,这个数组在某个位置是 True,当且仅当原来的数组在这个位置或者下一个位置是 True。现在你可以在这个新数组上使用 numpy.where() 来获取所有你想要的位置。

举个例子:

> a = numpy.array([False, False, True, True, False, False, True, False])
> a | numpy.r_[a[1:], False]
array([False,  True,  True,  True, False,  True,  True, False], dtype=bool)
0

假设我理解你的意思,你想找出那些元素为真(True)或者下一个元素为真的位置。你可以利用 shift 这个方法来实现。

s.index[s | s.shift(-1)]

举个例子:

>>> s = pd.Series([False, False, True, False, False, False, True, True])
>>> s
0    False
1    False
2     True
3    False
4    False
5    False
6     True
7     True
dtype: bool
>>> s | s.shift(-1)
0    False
1     True
2     True
3    False
4    False
5     True
6     True
7     True
dtype: bool
>>> s.index[s | s.shift(-1)]
Int64Index([1, 2, 5, 6, 7], dtype='int64')

撰写回答