Python 有效方法:查找列中几乎没有零出现的行

Python 有效方法:查找列中几乎没有零出现的行,python,pandas,Python,Pandas,我有一个问题需要尽可能有效地解决。我目前的方法是可行的,但速度非常慢 我有一个具有多列的数据框架,在本例中,我只关心其中一列。它包含正连续数和一些零。 我的目标:是找到以下行中几乎没有零出现的行 为了明确我的意思,我写了这个例子来复制我的问题: df = pd.DataFrame([0,0,0,0,1,0,1,0,0,2,0,0,0,1,1,0,1,2,3,4,0,4,0,5,1,0,1,2,3,4, 0,0,1,2,1,1,1,1,2,2,1,3,6,1,

我有一个问题需要尽可能有效地解决。我目前的方法是可行的,但速度非常慢

我有一个具有多列的数据框架,在本例中,我只关心其中一列。它包含正连续数和一些零。 我的目标:是找到以下行中几乎没有零出现的行

为了明确我的意思,我写了这个例子来复制我的问题:

df = pd.DataFrame([0,0,0,0,1,0,1,0,0,2,0,0,0,1,1,0,1,2,3,4,0,4,0,5,1,0,1,2,3,4,
                   0,0,1,2,1,1,1,1,2,2,1,3,6,1,1,5,1,2,3,4,4,4,3,5,1,2,1,2,3,4],
                   index=pd.date_range('2018-01-01', periods=60, freq='15T'))
开始时有一些零,但一段时间后它们会变少。 下面是我的未优化代码,用于可视化零的数量:

zerosum = 0 # counter for all zeros that have appeared so far
for i in range(len(df)):
    if(df[0][i]== 0.0):
        df.loc[df.index[i],'zerosum']=zerosum
        zerosum+=1
    else:
        df.loc[df.index[i],'zerosum']=zerosum
df['zerosum'].plot()

使用未优化的代码,我可以看到零随时间的分布

我的预期输出:在本例中是日期2018年1月1日08:00,因为该日期后不会出现零

我在处理真实数据时遇到的问题是,一些单零可能会在以后出现。因此,我不能只选择最后一行包含零。我必须以某种方式检查零的分布,忽略后来的异常值

注意:可视化并不是解决我的问题所必需的,我只是把它包括进来,以便尽可能好地解释我的问题。谢谢

好的

第二次尝试

import pandas as pd
import numpy as np
import math
df = pd.DataFrame([0,0,0,0,1,0,1,0,0,2,0,0,0,1,1,0,1,2,3,4,0,4,0,5,1,0,1,2,3,4,
                   0,0,1,2,1,1,1,1,2,2,1,3,6,1,1,5,1,2,3,4,4,4,3,5,1,2,1,2,3,4], 
                   index=pd.date_range('2018-01-01', periods=60, freq='15T'),
                   columns=['values'])
我们创建一个列,其中包含每个零的秩,如果存在非零值,则为零

df['zero_idx'] = np.where(df['values']==0,np.cumsum(np.where(df['values']==0,1,0)), 0)
我们可以使用此列获取任何秩的任何零的位置。我不知道你将零命名为异常值的标准是什么。但假设我们想确保至少超过所有零的90%

# Total number of zeros
n_zeros = max(df['zero_idx'])
# Get past at least this percentage
tolerance = 0.9
# The rank of the abovementioned zero
rank_tolerance = math.ceil(tolerance * n_zeros)

df[df['zero_idx']==rank_tolerance].index
Out[44]: DatetimeIndex(['2018-01-01 07:30:00'], dtype='datetime64[ns]', freq='15T')

这里是我的解决方案,使用过滤器和:

输出:

 2018-01-01 08:00:00

好的,如果需要在最后一个零发生后获取索引,可以尝试以下操作:

last = 0
for i in range(len(df)):
    if(df[0][i] == 0):
        last = i
print(df.iloc[last+1])
或通过过滤:

new = df.loc[df[0]==0]
last = df.index.get_loc(new.index[-1])
print(df.iloc[last+1])

谢谢你的回答。如果不出现异常值,该解决方案将是好的。也许我应该把它添加到我的例子中。我处理的真实数据要长得多,有时我会得到一个孤立点零。我已经根据你的评论编辑了我的答案
new = df.loc[df[0]==0]
last = df.index.get_loc(new.index[-1])
print(df.iloc[last+1])