Не удается выполнить операции прокатки окна pandas на основе времени? Всегда дает окно должно быть целым числом

Мои данные имеют вид

{'transaction': {'merchant': 'merchantA', 'amount': 20, 'time': '2019-02-13T10:00:00.000Z'}}
{'transaction': {'merchant': 'merchantA', 'amount': 90, 'time': '2019-02-13T11:00:00.000Z'}}
.
.
.

и я хочу выполнить некоторые операции прокатки в зависимости от времени. например, количество транзакций, которые произошли за последние «X» минут и т. д.

Я пробовал несколько способов, но не могу понять. Первоначально я указал len(df.index) в качестве индекса. (не знаю, эффективно ли это делать так)

Позже я также попытался указать data['transaction']['time'] в качестве индекса. все равно не работает.

Он всегда выдает, что окно ошибки должно быть целым числом.

df = pd.DataFrame()
    df2 = pd.DataFrame()
    for line in sys.stdin:
        data = json.loads(line)
        # df1 = pd.DataFrame(data["transaction"], index=[len(df.index)])
        df1 = pd.DataFrame(data["transaction"], index=[data['transaction']['time']])
        # df1 = pd.DataFrame.from_dict(data, orient='index')
        df = df.append(df1)
        ro = df.rolling('2min', on='time').count()
        # ro = pd.get_dummies(df).rolling('2M').count()
        print(ro)
        # df2 = df.merge(ro)

    # print(df2)
    print(df)

Что мне здесь не хватает?

Спасибо


person gamer    schedule 18.02.2020    source источник
comment
Я думаю, что проблема заключается в спецификации df.rolling(), поскольку она интерпретирует «2min» как строку. Вы пробовали ro = df.rolling('2m', on='time').count()?   -  person Carsten    schedule 18.02.2020
comment
ага. пробовал уже. 2м 2с и т.д. не работает   -  person gamer    schedule 18.02.2020


Ответы (1)


Я думаю, вы можете сначала создать список словарей и перейти к конструктору DataFrame, преобразовать столбец time в дату и время, а затем использовать rolling:

out = [json.loads(line)["transaction"] for line in sys.stdin]
df = pd.DataFrame(out)
df['time'] = pd.to_datetime(df['time'])

А потом:

df['new'] = df.rolling('2min', on='time')['amount'].count()
print (df)
    merchant  amount                      time  new
0  merchantA      90 2019-02-13 11:00:00+00:00  1.0
1  merchantA      90 2019-02-13 11:00:00+00:00  2.0

РЕДАКТИРОВАТЬ:

Ваше решение должно быть изменено:

out = []
for line in sys.stdin:
    data = json.loads(line)
    out.append(data["transaction"])

df = pd.DataFrame(out)
df['time'] = pd.to_datetime(df['time'])

df['new'] = df.rolling('2min', on='time')['amount'].count()
person jezrael    schedule 18.02.2020
comment
df = pd.DataFrame(out) Это приведет к ошибке, требующей индекса при указании скалярных значений. И я не могу использовать json.loads(line)["transaction"] for line in sys.stdin, потому что jsons, поступающие из потока, не обязательно совпадают. В некоторых вообще нет транзакции. Но я попробую преобразовать столбец времени - person gamer; 18.02.2020
comment
@gamer - Да, я думаю, что это ключ - преобразование в дату и время - person jezrael; 18.02.2020
comment
Я тоже это имел в виду. Но я пробовал, пример дает ту же ошибку, т.е. окно должно быть целым числом - person gamer; 18.02.2020
comment
Я думаю, что индекс должен быть в преобразованном формате DateTime. Тогда это может сработать, но я не уверен, как это сделать. - person gamer; 18.02.2020
comment
Я не могу собрать все данные в список, а затем выполнить вычисления как потоковое приложение. Но я понял идею. просто пришлось изменить формат времени. и применить to_datetime. И это работает. Спасибо! - person gamer; 18.02.2020
comment
Можете ли вы обсудить это, пожалуйста? stackoverflow.com/questions/60285964/ - person gamer; 18.02.2020