В моем наборе данных мне нужно найти, когда количество нулей повторяется более 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 раз.






Предположим, что этот пример и порог 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]
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. Спасибо!
@IrmakOzarslan конечно, я добавил цикл, но не стоит использовать его с пандами
Большое спасибо! У меня только один вопрос: в третьем подходе вы можете объяснить "x[0][0]"?
@Ирмак, конечно, поскольку мы groupby на enumerate, элементы представляют собой пары (index, value). Первый [0] получает первую пару, второй [0] получает индекс. Вы можете переписать это как классический цикл, чтобы увидеть промежуточные звенья;)
Можете ли вы создать небольшой пример с порогом 5 вместо 280 и предоставить соответствующий ожидаемый результат?