有效的方法:找到列中几乎没有零的行

问题描述 投票:3回答:3

我有一个问题,即尽可能高效地解决。我目前的做法有点有效,但速度极慢。

我有一个包含多列的数据框,在这种情况下我只关心其中一列。它包含正连续数和一些零。我的目标:找到几行中几乎没有零的行。

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

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'))

Plotted data一开始有一些零,但一段时间后它们会减少。这是我未优化的代码,用于可视化零的数量:

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()

Distribution of zeros

有了这个未经优化的代码,我可以看到零随时间的分布。

我的预期输出:在此示例中将是01-Jan-2018 08:00的日期,因为在该日期之后没有出现零。

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

注意:可视化对于解决我的问题不是必需的,我只是将其包括在内尽可能地解释我的问题。谢谢

python pandas
3个回答
1
投票

第二个去

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')

0
投票

好的,如果你需要在最后一个零发生后得到索引,你可以试试这个:

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])

0
投票

在这里我的解决方案使用过滤器和cumsum

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'))

a = df[0] == 0
df['zerosum'] = a.cumsum()

maxval = max(df['zerosum'])
firstdate = df[df['zerosum'] == maxval].index[1]
print(firstdate)

输出:

 2018-01-01 08:00:00
© www.soinside.com 2019 - 2024. All rights reserved.