У меня есть следующий фрейм данных:
1 2 3 4 5 6 7 8 9
0 0 0 1 0 0 0 0 0 1
1 0 0 0 0 1 1 0 1 0
2 1 1 0 1 1 0 0 1 1
...
Я хочу получить для каждой строки самую длинную последовательность со значением 0 в строке. поэтому ожидаемыми результатами для этого фрейма данных будет массив, который выглядит следующим образом:
[5,4,2,...]
как и в первой строке, максимальная последовательность значений 0 равна 5 и т. д.
Я видел сообщение это и пытался для начала получить это для первой строки (хотя я хотел бы сделать это сразу для всего фрейма данных), но получил ошибки:
s=df_day.iloc[0]
(~s).cumsum()[s].value_counts().max()
TypeError: ufunc 'invert' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
когда я вставил вручную такие значения:
s=pd.Series([0,0,1,0,0,0,0,0,1])
(~s).cumsum()[s].value_counts().max()
>>>7
Я получил 7, что является общим числом 0 в строке, но не максимальной последовательностью. Однако я не понимаю, почему сначала возникает ошибка, и, что более важно, я хотел бы запустить ее в конце в фрейме данных while и для каждой строки.
Моя конечная цель: получить максимальное непрерывное появление значения 0 в строке.
@jezrael не так много, но я всегда готов услышать больше решений :)






Следующий код должен выполнить эту работу.
функция longest_streak подсчитает количество последовательных нулей и вернет максимум, и вы можете использовать apply на своем df.
from itertools import groupby
def longest_streak(l):
lst = []
for n,c in groupby(l):
num,count = n,sum(1 for i in c)
if num==0:
lst.append((num,count))
maxx = max([y for x,y in lst])
return(maxx)
df.apply(lambda x: longest_streak(x),axis=1)
Использовать:
df = df.T.apply(lambda x: (x != x.shift()).astype(int).cumsum().where(x.eq(0)).dropna().value_counts().max())
OUTPUT
0 5
1 4
2 2
Вам нужно добавить условие, что значение равно 0
Векторизованное решение для подсчета последовательных 0 строк, поэтому для максимального использования max DataFrame c:
#more explain https://stackoverflow.com/a/52718619/2901002
m = df.eq(0)
b = m.cumsum(axis=1)
c = b.sub(b.mask(m).ffill(axis=1).fillna(0)).astype(int)
print (c)
1 2 3 4 5 6 7 8 9
0 1 2 0 1 2 3 4 5 0
1 1 2 3 4 0 0 1 0 1
2 0 0 1 0 0 1 2 0 0
df['max_consecutive_0'] = c.max(axis=1)
print (df)
1 2 3 4 5 6 7 8 9 max_consecutive_0
0 0 0 1 0 0 0 0 0 1 5
1 0 0 0 0 1 1 0 1 0 4
2 1 1 0 1 1 0 0 1 1 2
ваши решения всегда такие элегантные. Вы должны написать путеводитель по пандам :)
Производительность важна?