Переберите числа в столбце и получите номер первой строки, с которой начинается n повторений

В моем наборе данных мне нужно найти, когда количество нулей повторяется более 280 раз, и получить номер первой строки начала повторения в массиве. Я использую Python 3.11.

Образец данных:

различия

0
0
0
0
0
0
0
.
.
.
5
5
.
.
0
0
0
0

или создать образец набора данных:

   ACD=[0,5]

   df2 = pd.DataFrame(np.repeat(ACD, 100, axis=0))
   df3=df2.sample(frac=1,axis=1).sample(frac=1).reset_index(drop=True)

Пока мой код:

c=[]
for values,row in df.loc[:, ['differences']].iterrows():
        i=0
        while row['differences']  == 0:
            count = sum(1 for i in row)
            i +=1
            if count > 280:
                continue
            c.append(np.where(row['differences']))
        else:
            values+=1

Ожидаемый результат:

row_number_rep= [5,90,120] #showing the specific row numbers where the repetition stars.

С этим кодом я получаю ошибку

<stdin>:8: DeprecationWarning: вызов ненулевого значения для массивов 0d устарел, поскольку ведет себя неожиданно. Используйте atleast_1d(arr).nonzero(), если предполагалось старое поведение.

Мне нужна помощь, чтобы улучшить этот код. Я думаю, проблема в том, что у меня нет первых 280 элементов как 0, и мне нужно продолжать перебирать весь столбец, чтобы найти все номера строк, начиная с 0, повторяющиеся 280 раз.

Можете ли вы создать небольшой пример с порогом 5 вместо 280 и предоставить соответствующий ожидаемый результат?

mozway 07.03.2024 15:18
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
панды подход

Предположим, что этот пример и порог 4 (вместо 280):

df = pd.DataFrame({'differences': [0,0,0,0,0,1,2,0,3,0,0,0,0,0,0,4,0,5]})

    differences
0             0  # 0: first stretch of >4
1             0
2             0
3             0
4             0
5             1
6             2
7             0
8             3
9             0  # 9: second stretch of >4
10            0
11            0
12            0
13            0
14            0
15            4
16            0
17            5

Вы можете выполнить groupby.size , чтобы отфильтровать groupby.first:

thresh = 4

m = df['differences'].eq(0)
group = (~m).cumsum().to_numpy()

g = df.reset_index()[m].groupby(group[m])
g.size()

out = g['index'].first()[g.size()>thresh].to_numpy()

Вывод: array([ 0, 9])

циклический подход
lst = [0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0]
thresh = 4

start = -1
zeros = False
count = 0
out = []
for i, v in enumerate(lst+[-1]):
    if v==0:
        if not zeros:
            count = 0
            start = i
            zeros = True
        count += 1
        continue
    if count > thresh:
        if zeros:
            out.append(start)
    zeros = False

out
# [0, 9, 18]
itertools.groupby подход:
from itertools import groupby

lst = [0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0]
thesh  = 4

out = [x[0][0] for k,g in groupby(enumerate(lst), key=lambda x: x[1]==0)
       if k and len(x:=list(g))>thresh]
# [0, 9, 18]

Большое спасибо за этот ответ, так как он прост и отлично работает. Мне любопытно посмотреть, как это будет работать с циклом while. Спасибо!

Irmak Ozarslan 07.03.2024 15:49

@IrmakOzarslan конечно, я добавил цикл, но не стоит использовать его с пандами

mozway 07.03.2024 16:05

Большое спасибо! У меня только один вопрос: в третьем подходе вы можете объяснить "x[0][0]"?

Irmak Ozarslan 07.03.2024 17:24

@Ирмак, конечно, поскольку мы groupby на enumerate, элементы представляют собой пары (index, value). Первый [0] получает первую пару, второй [0] получает индекс. Вы можете переписать это как классический цикл, чтобы увидеть промежуточные звенья;)

mozway 07.03.2024 17:49

Другие вопросы по теме

Похожие вопросы