将一个Pandas DataFrame中的元素放置到另一个DataFrame中的元素位置



我有两个Pandas dataframe, df1和df2。

第一个使用0和1指定元素的"位置"。

第二个指定元素的值,但不指定它们的位置(即从Col1到Col4从左到右填充)。

df1 = pd.DataFrame([[1,0,0,0], [1,0,0,1], [0,1,0,1], [0,1,1,1]], columns=['Col1', 'Col2', 'Col3', 'Col4'])
df2 = pd.DataFrame([[1,0,0,0], [0.4,0.6,0,0], [0.8,0.2,0,0], [0.1,0.4,0.5,0]], columns=['Col1', 'Col2', 'Col3', 'Col4'])
df1
Col1 Col2 Col3 Col4
0    1    0    0    0
1    1    0    0    1
2    0    1    0    1
3    0    1    1    1
df2
Col1 Col2 Col3 Col4
0    1    0    0    0
1  0.4  0.6    0    0
2  0.8  0.2    0    0
3  0.1  0.4  0.5    0

我想创建第三个数据框架df3,它将df2中的非零值放在df1中的相应位置。我想从左到右工作,即df2每一行中最左边的非零元素应该放在df1中最左边的元素的位置。

df3 = pd.DataFrame([[1,0,0,0], [0.4,0,0,0.6], [0,0.8,0,0.2], [0,0.1,0.4,0.5]], columns=['Col1', 'Col2', 'Col3', 'Col4'])

df3
Col1 Col2 Col3 Col4
0    1    0    0    0
1  0.4    0    0  0.6
2    0  0.8    0  0.2
3    0  0.1  0.4  0.5

由于实际的dataframe相对较大,因此需要一个有效的解决方案(即遍历元素可能不是一个选项)。

提前感谢您的帮助!

如果您使用numpy,就会有一个非常有效的解决方案。有一种叫做place的方法正好可以满足你的需求。

# get series with right typing
values1 = df1.values.astype(np.float64)
values2 = df2.values.astype(np.float64)
#replace 1 values in the series1 with non zero values from series2
np.place(values1, values1==1, values2[values2 != 0])
# replace values in the dataframe1
df1.loc[:] = values1

我相信有更有效的解决方案,但你可以在两个dfs上使用melt,交换值(确保你保留顺序和索引)和pivot再次创建数据框架结构:

# Melt dataframes
melted_df1 = df1.reset_index().melt(id_vars="index").sort_values(by=["index","variable"])
melted_df2 = df2.reset_index().melt(id_vars="index").sort_values(by=["index","variable"])

熔化的输出:

index variable  value
0       0     Col1      1
4       0     Col2      0
8       0     Col3      0
12      0     Col4      0
1       1     Col1      1
5       1     Col2      0
9       1     Col3      0
13      1     Col4      1
2       2     Col1      0
6       2     Col2      1
10      2     Col3      0
14      2     Col4      1
3       3     Col1      0
7       3     Col2      1
11      3     Col3      1
15      3     Col4      1
index variable  value
0       0     Col1    1.0
4       0     Col2    0.0
8       0     Col3    0.0
12      0     Col4    0.0
1       1     Col1    0.4
5       1     Col2    0.6
9       1     Col3    0.0
13      1     Col4    0.0
2       2     Col1    0.8
6       2     Col2    0.2
10      2     Col3    0.0
14      2     Col4    0.0
3       3     Col1    0.1
7       3     Col2    0.4
11      3     Col3    0.5
15      3     Col4    0.0 
# Keep only non zero values in the melted lists
melted_df1 = melted_df1[melted_df1["value"] > 0]
melted_df2 = melted_df2[melted_df2["value"] > 0]

过滤后的熔化dfs输出:

index variable  value
0       0     Col1      1
1       1     Col1      1
13      1     Col4      1
6       2     Col2      1
14      2     Col4      1
7       3     Col2      1
11      3     Col3      1
15      3     Col4      1
index variable  value
0       0     Col1    1.0
1       1     Col1    0.4
5       1     Col2    0.6
2       2     Col1    0.8
6       2     Col2    0.2
3       3     Col1    0.1
7       3     Col2    0.4
11      3     Col3    0.5
# replace the first filtered melted values with the second
melted_df1["value"] = melted_df2["value"].to_list()

替换的熔化数据帧输出:

index variable  value
0       0     Col1    1.0
1       1     Col1    0.4
13      1     Col4    0.6
6       2     Col2    0.8
14      2     Col4    0.2
7       3     Col2    0.1
11      3     Col3    0.4
15      3     Col4    0.5
# pivot the result to get back to a the intial dataframe structure
df3 = melted_df1.pivot(index="index", columns="variable", values="value").fillna(0)

df3的输出:

variable  Col1  Col2  Col3  Col4
index
0          1.0   0.0   0.0   0.0
1          0.4   0.0   0.0   0.6
2          0.0   0.8   0.0   0.2
3          0.0   0.1   0.4   0.5

我把它写在这里作为答案。如果一个表是二进制的,你可以把数据帧相乘。

df3 = pd.DataFrame(df1.values*df2.values, columns=df.columns, index=df.index)

相关内容

  • 没有找到相关文章

最新更新