来自另一个数据帧的pandas multiindex赋值

Mat*_*yra 13 python variable-assignment multi-index pandas

我试图了解pandas MultiIndex DataFrames以及如何为它们分配数据.具体来说,我有兴趣分配与另一个较小数据帧匹配的整个块.

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这些都不起作用,它们将所有值保留df为as 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]
Run Code Online (Sandbox Code Playgroud)

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

有一个关于索引切片器的相关问题,但它是关于为掩码部分分配单个值DataFrame,而不是分配块. Pandas:根据多指标数据帧子集的条件设置值的正确方法

unu*_*tbu 21

当你使用

df.loc['A', :] = df_
Run Code Online (Sandbox Code Playgroud)

Pandas尝试将索引df_与子DataFrame的索引 对齐df.但是,在执行对齐的代码中,子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)
Run Code Online (Sandbox Code Playgroud)

成功,产生类似的东西

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
Run Code Online (Sandbox Code Playgroud)

当然,您可能不希望每次要分配值块时都必须创建新的MultiIndex.因此,要解决此对齐问题,可以使用NumPy数组作为赋值:

df.loc['A', :] = df_.values
Run Code Online (Sandbox Code Playgroud)

由于df_.values是NumPy数组且数组没有索引,因此不执行对齐, 并且赋值产生与上面相同的结果.当您不希望对齐索引时,使用NumPy数组的这一技巧适用于使用Pandas时的许多情况.

另请注意,NumPy数组赋值还可以帮助您执行更复杂的分配,例如不连续的行:

idx = pd.IndexSlice
df.loc[idx[:,('a','b')], :] = df_.values
Run Code Online (Sandbox Code Playgroud)

产量

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
Run Code Online (Sandbox Code Playgroud)

例如.