【问题标题】:pandas multiindex assignment from another dataframe来自另一个数据框的熊猫多索引分配
【发布时间】:2015-04-10 11:25:55
【问题描述】:

我想了解pandasMultiIndexDataFrames 以及如何为它们分配数据。具体来说,我有兴趣分配与另一个较小数据框匹配的整个块。

ix = pd.MultiIndex.from_product([['A', 'B'], ['a', 'b', 'c', 'd']])
df = pd.DataFrame(index=ix, columns=['1st', '2nd', '3rd'], dtype=np.float64)
df_ = pd.DataFrame(index=['a', 'b', 'c', 'd'], columns=['1st', '2nd', '3rd'], data=np.random.rand(4, 3))
df_

    1st     2nd     3rd
a   0.730251    0.468134    0.876926
b   0.104990    0.082461    0.129083
c   0.993608    0.117799    0.341811
d   0.784950    0.840145    0.016777

df 是一样的,只是所有的值都是NaN 并且有两个块AB。现在,如果我想将值从 df_ 分配到 df 我想我可以做类似的事情

df.loc['A',:] = df_                # Runs, does not work
df.loc[('A','a'):('A','d')] = df_  # AssertionError (??) 'Start slice bound is non-scalar'
df.loc[('A','a'):('A','d')]        # No AssertionError (??)

idx = pd.IndexSlice
df.loc[idx['A', :]] = df_          # Runs, does not work

这些都不起作用,它们将df 中的所有值保留为NaN,尽管df.loc[idx['A', :]] 为我提供了与子帧(df_)完全匹配的数据帧切片。那么这是在视图上设置值的情况吗?在df_ 中显式迭代索引工作

# this is fine
for v in df_.index:
    df.loc[idx['A', v]] = df_.loc[v]

# this is also fine
for v in df_.index:
    df.loc['A', v] = df_.loc[v]

甚至可以像这样分配整个块(有点像NumPy)?如果没有,那很好,我只是想了解系统是如何工作的。

有一个关于索引切片器的相关问题,但它是关于将单个值分配给DataFrame 的屏蔽部分,而不是关于分配块。 Pandas : Proper way to set values based on condition for subset of multiindex dataframe

【问题讨论】:

    标签: python pandas variable-assignment multi-index


    【解决方案1】:

    我不久前做了8480,这使得带有列的子框架分配工作。因此,您可以执行以下操作作为解决方法:

    >>> rf
         1st    2nd    3rd
    a  0.730  0.468  0.877
    b  0.105  0.082  0.129
    c  0.994  0.118  0.342
    d  0.785  0.840  0.017
    >>> df.T['A'] = rf.T  # take transpose of both sides
    >>> df
           1st    2nd    3rd
    A a  0.730  0.468  0.877
      b  0.105  0.082  0.129
      c  0.994  0.118  0.342
      d  0.785  0.840  0.017
    B a    NaN    NaN    NaN
      b    NaN    NaN    NaN
      c    NaN    NaN    NaN
      d    NaN    NaN    NaN
    

    也就是说,您可能希望将此作为错误发布在 github 上。

    编辑:似乎在最后添加一个虚拟切片也可以:

    >>> df.loc['A'][:] = rf
    >>> df
           1st    2nd    3rd
    A a  0.730  0.468  0.877
      b  0.105  0.082  0.129
      c  0.994  0.118  0.342
      d  0.785  0.840  0.017
    B a    NaN    NaN    NaN
      b    NaN    NaN    NaN
      c    NaN    NaN    NaN
      d    NaN    NaN    NaN
    

    【讨论】:

    • 最后的虚拟索引不会创建view 记录的数据框here - 我至少收到有关为视图分配值的警告
    • 编辑后的建议对我有用,谢谢!
    【解决方案2】:

    当你使用时

    df.loc['A', :] = df_
    

    Pandas 尝试将 df_ 的索引与子 DataFrame 的索引对齐 df。但是,在执行对齐的point in the code, sub-DataFrame 有一个 MultiIndex,而不是您看到的单个索引作为结果 df.loc['A', :].

    所以对齐失败是因为 df_ 有一个索引,而不是 MultiIndex 是需要的。要查看df_ 的索引确实是问题所在,请注意

    ix_ = pd.MultiIndex.from_product([['A'], ['a', 'b', 'c', 'd']])
    df_.index = ix_
    df.loc['A', :] = df_
    print(df)
    

    成功,产生类似的东西

    A a  0.229970  0.730824  0.784356
      b  0.584390  0.628337  0.318222
      c  0.257192  0.624273  0.221279
      d  0.787023  0.056342  0.240735
    B a       NaN       NaN       NaN
      b       NaN       NaN       NaN
      c       NaN       NaN       NaN
      d       NaN       NaN       NaN
    

    当然,您可能不希望每次都创建一个新的 MultiIndex 你想分配一个值块的时间。所以相反,要解决这个问题 对齐问题,可以使用 NumPy 数组作为赋值:

    df.loc['A', :] = df_.values
    

    由于df_.values 是一个 NumPy 数组并且数组没有索引,no alignment is performed 并且分配产生与上述相同的结果。当您不想对齐索引时使用 NumPy 数组的这个技巧 在使用 Pandas 时适用于许多情况。

    另请注意,NumPy-array 分配也可以帮助您执行更复杂的分配,例如不连续的行:

    idx = pd.IndexSlice
    df.loc[idx[:,('a','b')], :] = df_.values
    

    产量

    In [85]: df
    Out[85]: 
              1st       2nd       3rd
    A a  0.229970  0.730824  0.784356
      b  0.584390  0.628337  0.318222
      c       NaN       NaN       NaN
      d       NaN       NaN       NaN
    B a  0.257192  0.624273  0.221279
      b  0.787023  0.056342  0.240735
      c       NaN       NaN       NaN
      d       NaN       NaN       NaN
    

    例如。

    【讨论】:

    • 我知道这是一个很好的解释,谢谢。我喜欢df_.values,尤其是因为它可以让你做各种疯狂的部分作业。只需要小心以相同的顺序索引数据帧,我想知道为什么我的一些数据突然翻转(哎呀)。
    • 如果值的顺序不同,那么将df_ 的索引设为 MultiIndex 并让 Pandas 为您处理对齐可能是最简单的。
    • 顺序不同,因为我很愚蠢,但我会记住这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 2017-11-03
    • 2014-03-17
    • 1970-01-01
    • 2016-06-13
    • 2015-10-22
    • 1970-01-01
    相关资源
    最近更新 更多