Разрежьте DataFrame в определенных точках и постройте каждый срез

Я новичок в программировании и Python, не могли бы вы мне помочь? У меня есть кадр данных, который выглядит так.

d = {'time': [4, 10, 15, 6, 0, 20, 40, 11, 9, 12, 11, 25], 
     'value': [0, 0, 0, 50, 100, 0, 0, 70, 100, 0,100, 20]}    
df = pd.DataFrame(data=d)

Я хочу срезать данные всякий раз, когда value == 100, а затем отображать все срезы на рисунке. Итак, мои вопросы заключаются в том, как нарезать или вырезать данные, как описано? и какая структура лучше всего сохраняет фрагменты для построения графика?

Примечание 1: в столбце значений нет частоты, которую я могу использовать, и она варьируется от 0 до 100, где время произвольно.

Примечание 2. Я уже пробовал это решение, но получаю ту же таблицу.

decreased_value = df[df['value'] <= 100][['time', 'value']].reset_index(drop=True)

Как я могу разделить один столбец в кадре данных на несколько рядов на основе условия

Заранее спасибо!


person fdaa Cham    schedule 01.04.2021    source источник
comment
Попробуйте slices = df.loc[df['value'] == 100, :]   -  person Eric Truett    schedule 01.04.2021
comment
Благодарность! в этом случае я получаю только строки, где значение == 100, но я хочу получить в каждом фрагменте все данные до значения == 100   -  person fdaa Cham    schedule 01.04.2021
comment
Итак, вы хотите разбить приведенный выше пример на четыре слайса, где последняя строка каждого слайса — 100?   -  person Kristian Canler    schedule 03.04.2021


Ответы (2)


ИЗМЕНИТЬ:

Вот более простой способ обработки моего первого ответа (спасибо @aneroid за предложение).

Получите индексы, где value==100 и добавьте +1, чтобы они оказались внизу каждого среза:

indices = df.index[df['value'] == 100] + 1

Затем используйте numpy.split (спасибо этот ответ для этого метода), чтобы составить список фреймов данных:

df_list = np.split(df, indices)

Затем сделайте свой график для каждого среза в цикле for:

for df in df_list:
     --- plot based on df here ---

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ / МЕТОД С НУЛЯ:

Вы можете получить индексы для где value==100 следующим образом:

indices = df.index[df.value==100]

Затем добавьте наименьший и наибольший индексы, чтобы не пропустить начало и конец df:

indices = indices.insert(0,0).to_list()
indices.append(df.index[-1]+1)

Затем выполните цикл while, чтобы разрезать кадр данных и поместить каждый фрагмент в список кадров данных:

i = 0
df_list = []
while i+1 < len(indices):
    df_list.append(df.iloc[indices[i]:indices[i+1]])
    i += 1
person Kristian Canler    schedule 02.04.2021
comment
Пришел сюда из вашего связанного вопроса. Это может быть уменьшено до indices = df.index[df['value'] == 100], а затем df_list = np.split(df, indices), поскольку первая часть перед первым индексом для разделения в любом случае является первой частью. Нет необходимости явно добавлять первый и последний индексы, поскольку это даст пустой кадр данных в качестве первого элемента. - person aneroid; 03.04.2021
comment
Отличный момент. Я проверил это, но, должно быть, я сделал это неправильно, потому что казалось, что numpy не сохранил начало и конец. Однако вам нужно добавить +1 к каждому из индексов для варианта использования здесь. - person Kristian Canler; 03.04.2021
comment
Действительно, если ОП хочет, чтобы каждый фрагмент заканчивался на value 100 (что мне не ясно из их вопроса), тогда добавьте 1 к индексам. Тем не менее, вариант использования окончания на 100 для чего-то, повторяющегося от 0 до 100, имеет смысл хотеть сделать. - person aneroid; 03.04.2021
comment
отличная идея задать вопрос о SO, чтобы улучшить свой ответ на другой вопрос :) - person Ben.T; 03.04.2021
comment
@Ben.T Я уверен, что это будет первый из многих раз, ха-ха :) - person Kristian Canler; 03.04.2021
comment
спасибо за ваш ответ @k_n_c и за всестороннее обсуждение @aneroid. Я уже решил проблему, на самом деле то, что я искал, это функция np.split, но я сделал это с помощью цикла for следующим образом: slices = df[df['score'] == 100].index.values slices = slices + 1 slices = np.insert(slices, 0,0, axis=0) prev_ind = 0 for ind in slices: temp = df.iloc[prev_ind:ind,:] plt.plot(temp.time, temp.score) prev_ind = ind plt.show() и я добавил примечание, чтобы завершить прошлую часть df, которую вы сделали так indices.append(df.index[-1]+1) - person fdaa Cham; 03.04.2021
comment
Код с разрывами строк не должен размещаться в строке (мы не можем его прочитать!). Если он существенно отличается от любого из текущих ответов, вы можете опубликовать его как ответ на свой вопрос. - person Kristian Canler; 03.04.2021

Я уже решил проблему, используя for loop, который можно использовать для одновременного нарезки и построения графика без использования функции np.split, а также для поддержания структуры данных. Благодаря предыдущему ответу @k_n_c, он помогает мне улучшить его.

slices = df.index[df['score'] == 100]
slices = slices + 1

slices = np.insert(slices, 0,0, axis=0)
slices = np.append(slices,df.index[-1]+1)

prev_ind = 0
for ind in slices:
    temp = df.iloc[prev_ind:ind,:] 
    plt.plot(temp.time, temp.score)
    prev_ind = ind
plt.show() 
person fdaa Cham    schedule 06.04.2021