Pandas DataFrame: невозможно перебрать сгруппированные серии - PullRequest
0 голосов
/ 14 января 2019

Итак, у меня есть следующие серии Panda grouped:

                               Amount
Ticker Unit   Date       Time        
FLWS   SHARES 2019-01-03 -       20.0
              2019-01-13 -       20.0
PIH    SHARES 2019-01-13 -      -10.0
       VALUE  2019-01-03 -      -25.0

* Я хотел сбросить индекс, чтобы удалить значение «Сумма» как мультииндекс и «выпадающий список», но затем группировка не выполняется, и это происходит только после преобразования Series в DataFrame.

Я пытаюсь перебрать группы:

    for ticker, action, date, time in grouped:
        print(ticker)
        print(action)
        print(date)
        print(time)

но я получаю следующее: TypeError: 'float' object is not iterable

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Я получаю упомянутый фрейм данных из следующего:

orders = pd.DataFrame(OrderedDict([
        ('Ticker', tickers),
        ('Action', actions),
        ('Unit', units),
        ('Amount', amounts),
        ('Date', dates),
        ('Time', times),
    ]))

    df_orders = pd.DataFrame(orders)
if not df_orders.empty:
    df_orders.loc[df_orders['Action'] == 'SELL', 'Amount'] *= -1
    grouped = df_orders.groupby(['Ticker', 'Unit', 'Date', 'Time'])['Amount'].apply(np.sum) 

    print(grouped)

, где tickers, actions, units и т. Д. - все списки

EDIT: Я подумал, что было бы лучше показать логику, в которой я хотел бы обрабатывать полученные данные.

total = 0
for ticker in tickers: 
    for date in dates:    
        if unit=='SHARES':
            total += some_function(ticker, date)
        else:
            total += some_function(ticker, date)  

обратите внимание, в этом случае каждый тикер в тикерах будет уникальным. Так как бы вы перебрали сгруппированные серии таким образом?

1 Ответ

0 голосов
/ 14 января 2019

Проблема в том, что, просто перебирая саму grouped, вы перебираете значения в Серии, которые являются просто значениями в столбце Amount. Также обратите внимание, что ticker, action, date и time являются индексами Серии, а не ее значениями. Таким образом, вы пытаетесь присвоить ticker, action, date, time одному float. Отсюда и ошибка TypeError: 'float' object is not iterable. В Python 3 ошибка немного более полезна, как TypeError: cannot unpack non-iterable float object.

Чтобы исправить это, вы должны использовать метод iteritems ( docs ) класса Pandas Series. Это повторяет каждый элемент в Серии и возвращает индекс и значение в виде кортежа на каждой итерации. Поскольку у вас есть составной индекс, этот индекс также будет кортежем, который можно распаковать в разные значения примерно так:

for (ticker, action, date, time), amount in grouped.iteritems():
    print(ticker)
    print(action)
    print(date)
    print(time)

Редактировать: [Обращаясь к редактированию вопроса.]

В предоставленном вами примере кода тикеры в некотором смысле уникальны, однако вы вызываете some_function на одном и том же тикере, возможно, несколько раз, поэтому тикеры не обязательно должны быть уникальными. Возможно, вы можете сделать что-то вроде этого:

grouped = df_orders.groupby(['ticker', 'date', 'unit'])['amount'].agg(sum)

total = 0
for (ticker, date, unit), amount in grouped.iteritems():
    if unit == 'SHARES':
        total += share_function(ticker, date)
    else:
        total += other_function(ticker, date)
...