Pandas DataFrame:无法遍历分组系列

时间:2019-01-13 23:38:46

标签: python pandas loops dataframe pandas-groupby

所以我有以下熊猫系列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)

其中tickersactionsunits等都是列表

编辑: 我认为最好显示出我想要处理所获取数据的逻辑。

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 :(得分:1)

问题在于,仅对grouped本身进行迭代,就可以对Series中的值进行迭代,而这些值只是Amount列中的值。还请注意,tickeractiondatetime是该系列的索引,而不是其值。因此,您试图将ticker, action, date, time分配给单个浮点数。因此,错误TypeError: 'float' object is not iterable。在Python 3中,该错误比TypeError: cannot unpack non-iterable float object更有帮助。

要解决此问题,应使用Pandas Series类的iteritemsdocs)方法。这将遍历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)