Python Dataframe:combining/replacing 多索引列和单索引列
Python Dataframe: combining/replacing multi-index columns with single index columns
我的 df 中有多个索引列。在我的 df 中,所有值都是 1 或 0,表示布尔值。我的任务是用另一个 df_test 数据帧中的值替换为“1”的值。见下文。
In [221]: df
Out[221]:
first bar baz
second one two one two
0 0 1 0 0
1 1 0 1 1
2 0 0 0 1
3 0 0 0 0
4 1 1 1 1
..............(continues)
我的 df_test 有常规列(不是多索引)和应该进入 df 的值。
In [222]: df_test
Out[222]:
amount
0 38
1 2179
2 191
3 4
4 19823
..............(continues)
两个数据帧匹配的索引和我的输出应该是:
In [223]: df
Out[223]:
first bar baz
second one two one two
0 0 38 0 0
1 2179 0 2179 2179
2 0 0 0 191
3 0 0 0 0
4 19823 19823 19823 19823
..............(continues)
请注意,我的 df 可以没有像 index = 3 这样的“1”值,或者像 index = 4 这样的全“1”值。如果有有效的方法来设置我的数据框
您想使用 pd.DataFrame.mask
并使用列 amount
作为替代。但是,您需要提供 axis=0
参数来告诉 Pandas 在索引上对齐。
df.mask(df.eq(1), df_test.amount, axis=0)
first bar baz
second one two one two
0 0 38 0 0
1 2179 0 2179 2179
2 0 0 0 191
3 0 0 0 0
4 19823 19823 19823 19823
设置
df = pd.DataFrame(
[[0, 1, 0, 0],
[1, 0, 1, 1],
[0, 0, 0, 1],
[0, 0, 0, 0],
[1, 1, 1, 1]],
columns=pd.MultiIndex.from_product(
[['bar', 'baz'], ['one', 'two']],
names=['first', 'second']
)
)
df_test = pd.DataFrame(dict(amount=[38, 2179, 191, 4, 19823]))
要获得结果,您可以使用广播乘法 -
v = df.values * df_test.amount.values[:, None]
v
array([[ 0, 38, 0, 0],
[ 2179, 0, 2179, 2179],
[ 0, 0, 0, 191],
[ 0, 0, 0, 0],
[19823, 19823, 19823, 19823]])
要取回原始数据框,只需调用 DataFrame
构造函数 -
df = pd.DataFrame(v, columns=df.columns, index=df.index)
df
first bar baz
second one two one two
0 0 38 0 0
1 2179 0 2179 2179
2 0 0 0 191
3 0 0 0 0
4 19823 19823 19823 19823
感谢 piRSquared 的 .
借来的设置
我的 df 中有多个索引列。在我的 df 中,所有值都是 1 或 0,表示布尔值。我的任务是用另一个 df_test 数据帧中的值替换为“1”的值。见下文。
In [221]: df
Out[221]:
first bar baz
second one two one two
0 0 1 0 0
1 1 0 1 1
2 0 0 0 1
3 0 0 0 0
4 1 1 1 1
..............(continues)
我的 df_test 有常规列(不是多索引)和应该进入 df 的值。
In [222]: df_test
Out[222]:
amount
0 38
1 2179
2 191
3 4
4 19823
..............(continues)
两个数据帧匹配的索引和我的输出应该是:
In [223]: df
Out[223]:
first bar baz
second one two one two
0 0 38 0 0
1 2179 0 2179 2179
2 0 0 0 191
3 0 0 0 0
4 19823 19823 19823 19823
..............(continues)
请注意,我的 df 可以没有像 index = 3 这样的“1”值,或者像 index = 4 这样的全“1”值。如果有有效的方法来设置我的数据框
您想使用 pd.DataFrame.mask
并使用列 amount
作为替代。但是,您需要提供 axis=0
参数来告诉 Pandas 在索引上对齐。
df.mask(df.eq(1), df_test.amount, axis=0)
first bar baz
second one two one two
0 0 38 0 0
1 2179 0 2179 2179
2 0 0 0 191
3 0 0 0 0
4 19823 19823 19823 19823
设置
df = pd.DataFrame(
[[0, 1, 0, 0],
[1, 0, 1, 1],
[0, 0, 0, 1],
[0, 0, 0, 0],
[1, 1, 1, 1]],
columns=pd.MultiIndex.from_product(
[['bar', 'baz'], ['one', 'two']],
names=['first', 'second']
)
)
df_test = pd.DataFrame(dict(amount=[38, 2179, 191, 4, 19823]))
要获得结果,您可以使用广播乘法 -
v = df.values * df_test.amount.values[:, None]
v
array([[ 0, 38, 0, 0],
[ 2179, 0, 2179, 2179],
[ 0, 0, 0, 191],
[ 0, 0, 0, 0],
[19823, 19823, 19823, 19823]])
要取回原始数据框,只需调用 DataFrame
构造函数 -
df = pd.DataFrame(v, columns=df.columns, index=df.index)
df
first bar baz
second one two one two
0 0 38 0 0
1 2179 0 2179 2179
2 0 0 0 191
3 0 0 0 0
4 19823 19823 19823 19823
感谢 piRSquared 的