pandas 来自另一个数据框的多索引分配
pandas multiindex assignment from another dataframe
我正在尝试了解 pandas
MultiIndex
DataFrame
以及如何为它们分配数据。具体来说,我有兴趣分配与另一个较小数据框匹配的整个块。
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
并且有两个块A
和B
外,其他都是一样的。现在,如果我想将 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
None 这些工作,他们将 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
的屏蔽部分,而不是关于分配块。
我不久前做过 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
就是说,您可能希望 post 这是 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
当你使用
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数组并且数组没有索引,没有对齐
执行
并且分配产生与上述相同的结果。当你不想索引对齐时使用 NumPy 数组的技巧
在使用 Pandas.
时适用于许多情况
另请注意,NumPy 数组赋值还可以帮助您执行更复杂的赋值,例如对不连续的行进行赋值:
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
例如
我正在尝试了解 pandas
MultiIndex
DataFrame
以及如何为它们分配数据。具体来说,我有兴趣分配与另一个较小数据框匹配的整个块。
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
并且有两个块A
和B
外,其他都是一样的。现在,如果我想将 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
None 这些工作,他们将 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
的屏蔽部分,而不是关于分配块。
我不久前做过 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
就是说,您可能希望 post 这是 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
当你使用
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数组并且数组没有索引,没有对齐
执行
并且分配产生与上述相同的结果。当你不想索引对齐时使用 NumPy 数组的技巧
在使用 Pandas.
另请注意,NumPy 数组赋值还可以帮助您执行更复杂的赋值,例如对不连续的行进行赋值:
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
例如