Python: я хотел бы вернуть подмножество фрейма данных на основе списка, если записи упорядочены так же, как и список - PullRequest
0 голосов
/ 05 мая 2020

У меня есть фрейм данных, содержащий более тысячи записей, и я хотел бы вернуть нарезанный фрейм данных, где значения упорядочены аналогично списку.

например,

lst = [0,1,0,0,0,1]

Вход

    date season hot_or_cold
 0   2012-01-01 Winter 0
 1   2012-01-02 Winter 1
 2   2012-01-03 Winter 0
 3   2012-01-04 Winter 0
 4   2012-01-05 Winter 0
 5   2012-01-06 Winter 1
 6   2012-01-07 Winter 1
 7   2012-01-08 Winter 1
 8   2012-01-09 Winter 0
 9   2012-01-10 Winter 1
 10   2012-01-11 Winter 0
    # 1 - hot
    # 0 - cold

Вывод

    date season hot_or_cold
 0   2012-01-01 Winter 0
 1   2012-01-02 Winter 1
 2   2012-01-03 Winter 0
 3   2012-01-04 Winter 0
 4   2012-01-05 Winter 0
 5   2012-01-06 Winter 1

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

Ответы [ 3 ]

0 голосов
/ 05 мая 2020

basi c вопрос заключается в поиске некоторого шаблона в фрейме данных, и я получил это здесь и реализовал то же самое.

import pandas as pd 
import numpy as np

arr = [0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1]
df = pd.DataFrame(data = arr, columns=['binary'])
pattern = [0,1, 0, 0, 0, 1]

matched = df.rolling(len(pattern)).apply(lambda x:all(np.equal(x, pattern)))
matched = matched.sum(axis = 1).astype(bool)   #Sum to perform boolean OR

idx_matched = np.where(matched)[0]
subset = [range(match-len(pattern)+1, match+1) for match in idx_matched]

result = pd.concat([df.iloc[subs,:] for subs in subset], axis = 0)

result
0 голосов
/ 06 мая 2020

другой способ с функцией накопления

from itertools import accumulate
import pandas as pd 
def accum(x):
    return list(accumulate(x))

lst = [0,1,0,0,0,1]
f = lambda x : accum([[i] for i in x])
b = df.groupby(['season'])['hot_or_cold'].apply(f)
df['col_accum2']  =  [(('Match ' if item[-len(lst):] == lst else 'NotMatch') if len(item) >= len(lst) else 'small list'  ) for subitem in b for item in subitem]
0 голосов
/ 05 мая 2020

Определите 2 следующие функции:

  1. Найдите совпадение между s (a Series , длиннее) и lst (список, короче).

    def fndMatch(s, lst):
        len1 = s.size
        len2 = len(lst)
        for i1 in range(len1 - len2 + 1):
            i2 = i1 + len2
            if s.iloc[i1:i2].eq(lst).all():
                return (i1, i2)
        return (None, None) 
    

    Когда совпадение найдено, результатом являются обе границы среза, в противном случае - пара значений Нет .

  2. Получить фрагмент df с hot_or_cold сопоставлением столбцов lst :

    def getFragment():
        i1, i2 = fndMatch(df.hot_or_cold, lst)
        if i1 is None:
            return None
        else:
            return df.iloc[i1:i2]
    

Когда вы называете это (getFragment()), результат:

         date  season  hot_or_cold
0  2012-01-01  Winter            0
1  2012-01-02  Winter            1
2  2012-01-03  Winter            0
3  2012-01-04  Winter            0
4  2012-01-05  Winter            0
5  2012-01-06  Winter            1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...