【问题标题】:How to assign dataframe to panel from a function return如何从函数返回将数据框分配给面板
【发布时间】:2016-08-01 15:31:05
【问题描述】:

我有一个返回面板和数据框的函数。例如,

def fo(pn,df)
  some update on pn,df
  return pn, df

然后我需要调用fo函数来更新pn4和pn3,如下所示,

pn4.loc[0], pn3.loc[0] = fo(pn,df)

其中 pn4 是 Panel4 结构,pn3 是 Panel。据我所知, pn4.loc[0] 应该是一个面板, pn3.loc[0] 应该是一个数据框。但是当我运行此类代码时收到一条错误消息

NotImplementedError:还不能使用带有面板的索引器进行设置!

那么我该如何解决这个错误呢?提前致谢。

有关更多信息,我在下面发布我的代码:

def update(x, UC, SC, A, U): # accelerated version, examined on 07/15 

    for a in A:
        UC_old = UC.copy()
        for u in U:
            UC.loc[a,:,u] = UC_old.loc[a,:,u] - UC_old.loc[a,:,x] * UC_old.loc[a,x,u]
        SC_old = SC.copy()
        SC.loc[:,a] = SC_old.loc[:,a] + UC_old.loc[a,x,:] * (1 - SC_old.loc[x,a])

    return UC, SC


def Streaming(UC, Au, k, U, A):
    ep = 0.01
    SC = pd.DataFrame(0.0, index = U, columns = A)
    max_mg = 0    
    for x in U:
        mg = computeMG(x, UC, SC, Au, A, U)
        max_mg = mg if mg > max_mg else max_mg
    del SC
    C = []
    S = {}
    m = max_mg
    while (m <= k*max_mg):
        C.append(m)
        S[m] = []        
        m = m * (1+ep)
    print len(C)
    UCC = pd.Panel4D(dict([(c, UC.copy()) for c in C]))           
    SCC = pd.Panel(0., items = C, major_axis = U, minor_axis = A)
    for x in U:
        for c in C:
            if (computeMG(x, UCC.loc[c], SCC.loc[c], Au, A, U) > c/float(2*k)) and (len(S[c])<k):
                S[c].append(x)
                UCC.loc[c], SCC.loc[c] = update(x, UCC.loc[c], SCC.loc[c], A, U) # where the error happens
    max_val = 0
    for c in C:
        val = 0
        for u in U:
            Tsu = 0
            for a in A:
                Tsu += SCC.loc[c,u,a]
            Tsu = Tsu / float(Au.loc[u])
            val += Tsu
        if val > max_val:
            S = S[c]
            max_val = val
    return S, max_val

【问题讨论】:

  • 关于更多信息,我的python文件中的真实代码类似于UCC.loc[c], SCC.loc[c] = update(x, UCC.loc[c], SCC.loc[c], A, U)

标签: python pandas dataframe panel


【解决方案1】:

对于数据框和系列,您可以使用lociloc(以及atiat)来获取和设置。这需要编码才能实现。您看到的错误

NotImplementedError:还不能使用带有面板的索引器进行设置!

表示尚未有人在面板上实现它。

你应该可以用

pn4[0], pn3[0] = fo(pn,df)

【讨论】:

  • 是的,pn4[0], pn3[0] = fo(pn,df) 有效。但是你能告诉我为什么loc会导致错误信息吗?
  • @Wedoso 我在帖子中说明了原因。它旨在按您的预期工作。然而,pandas 的贡献者还没有坐下来编写实现这一目标所需的代码。因此出现“NotImplementedError”,因为我们还没有实现它。和评论,“还不能设置使用带有面板的索引器!”。他们的意思是它会以这种方式工作,并且有一天它可能会。
【解决方案2】:

fo中的返回类型是dataframe;但是,在代码的最后一行中,您将 pn4.loc[0]pn3.loc[0] 分配给数据框对象。 pn.4loc[0]pn3.loc[0] 可以是 Pandas 系列,这就是您看到错误的原因,因为索引是 .

将您的返回命令设为return pn.loc[0], df.loc[0],您可能可以解决问题。

以下是Pandas 0.15.1 中描述您遇到的 NonImplementError 的源代码部分:

def _align_panel(self, indexer, df):
        is_frame = self.obj.ndim == 2
        is_panel = self.obj.ndim >= 3
        raise NotImplementedError("cannot set using an indexer with a Panel 
                                  yet!")

如您所见,如果框架和面板的尺寸不匹配,则会引发错误。

【讨论】:

  • 感谢您的快速回复,但如果我返回 pn.loc[0],df.loc[0],pn.loc[0] 将成为数据框,df.loc[0]会变成一个系列,这不是我想要的。实际上,我会返回整个 pn 和 df 以更新 pn4 中的面板和 pn3 中的数据框。
  • 那么你只是想更新pn4和pn3,而不是生成新的对象?
  • 不,我不想生成任何新对象。我唯一需要做的就是更新 pn4 和 pn3。我在上面添加了我的代码。您可以查看它们以获取详细信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多