我如何合并 2 个数据帧及其推导(如果类型不是对象)
How can i merge 2 dataframes and their deduction(in case the type is not object)
我有 2 个具有相同列和行号的数据框,其中一些数据框的列是日期(每个数据框 1 个),其他的是浮点数和存储字符串的对象。
让我们以下面的 df1 为例进行简化(我的实际数据框有数百列):
Date Val0 Val1
0 2020-09-29 13:22:57 char1 5.34
1 2020-09-29 13:23:12 char2 4.5
2 2020-09-29 13:23:44 char3 Nan
3 2020-09-29 13:24:01 char4 24
val0
在那个例子中是一个对象
df2
看起来像:
Date Val0 Val1
0 2020-09-29 13:22:58 char6 Nan
1 2020-09-29 13:23:12 char4 89.77
2 2020-09-29 13:23:45 Nan
3 2020-09-29 13:24:01 char4 24
预计
Date Date Val0 Val0 Val1 Val1 Val1
0 2020-09-29 13:22:57 2020-09-29 13:22:58 char1 char6 5.34 Nan 5.34
1 2020-09-29 13:23:12 2020-09-29 13:23:12 char2 char4 4.5 89.77 -85.27
2 2020-09-29 13:23:44 2020-09-29 13:23:45 char3 Nan Nan Nan
3 2020-09-29 13:24:01 2020-09-29 13:24:01 char4 char4 24 24 0
正如我们所看到的,浮点数被扣除了,我们有一个新的列有差异,而具有相同列的对象现在是 'next to one another'
我确实意识到使用相同的列名可能不是方法,例如,如果我们想删除一个或 pandas 默认添加的 .2
,对我来说是列名在这个阶段,它们可以是任何东西,因为它们已按照演示对齐,并且在写入 excel 时仍会帮助我进行下一步,这仅合并行名称,例如我们有一个
单元格下面有 2 列,同时它也是 val1
的 1 行名称和下面的 3 列。
My code and approach:
我想去掉我不能扣除的东西,在本例中是 val0
,所以我从复制的数据框中删除了 df1
和 df2
的那一列,然后扣除了结果 dfs 给了我 val1 的最后一列和日期的扣除以防万一我想要它。然后连接 df1
和 df_2
看起来像下面对应 df_6
:
df_minus = df_2 - df
df5 = pd.concat([df_2, df], axis=1)
df_6 = df5[list(sum(zip(df_2.columns, df.columns), ()))]
print(df_6)
Date Date Val0 Val0 Val1 Val1
0 2020-09-29 13:22:57 2020-09-29 13:22:58 char1 char6 5.34 Nan
1 2020-09-29 13:23:12 2020-09-29 13:23:12 char2 char4 4.5 89.77
2 2020-09-29 13:23:44 2020-09-29 13:23:45 char3 Nan Nan
3 2020-09-29 13:24:01 2020-09-29 13:24:01 char4 char4 24 24
我的方法确实解决了列是对象的问题,但是对于浮点数,我虽然以某种方式使用 df_minus 但找不到 way.Some 可能认为我应该简单地从中获取该列df_minus
并将其添加到 df_6
但请记住,我的实际数据有数百列,所以这不是一个选项。
这是一种方法,应该可以让您实现我认为您正在尝试做的事情。
我们确定减法运算对其有意义的数字列,然后进行减法并使用结果更新 df_minus
,其中一个输入数据帧的副本。然后,我们通过为减法结果附加“.diff”或为减法结果附加“.delete”(标记为将来删除)来重命名 df2
中的列,方法是附加后缀“.2”和 df_minus
中的列所有其他列。
然后我们使用您的列排序逻辑,但使用 3 个数据框而不是 2 个,因此结果中有 df1
、df2
和 df_minus
。最后,我们删除来自 df_minus
.
的不需要的列
import pandas as pd
import numpy as np
df1 = pd.DataFrame([
{'Date':'2020-09-29 13:22:57','Val0':'char1','Val1':5.34},
{'Date':'2020-09-29 13:23:12','Val0':'char2','Val1':4.5},
{'Date':'2020-09-29 13:23:44','Val0':'char3','Val1':np.NaN},
{'Date':'2020-09-29 13:24:01','Val0':'char4','Val1':24}
])
df2 = pd.DataFrame([
{'Date':'2020-09-29 13:22:58','Val0':'char6','Val1':np.NaN},
{'Date':'2020-09-29 13:23:12','Val0':'char4','Val1':89.77},
{'Date':'2020-09-29 13:23:45','Val0':'', 'Val1':np.NaN},
{'Date':'2020-09-29 13:24:01','Val0':'char4','Val1':24}
])
print(f"df1:\n{df1}\n")
print(f"df2:\n{df2}\n")
dfNumericCols = set(c for c in df1.columns if isinstance(df1.loc[0,c], (float,int)))
df_minus = df1.copy(deep=True)
df_minus[list(dfNumericCols)] = df1[list(dfNumericCols)] - df2[list(dfNumericCols)]
df_minus.rename(columns={c:c+'.diff' if c in dfNumericCols else c+'.delete' for c in df_minus.columns}, inplace=True)
print(f"df_minus:\n{df_minus}\n")
df2.rename(columns={c:c+'.2' for c in df2.columns}, inplace=True)
df5 = pd.concat([df1, df2, df_minus], axis=1)
df6 = df5[list(sum(zip(df1.columns, df2.columns, df_minus.columns), ()))]
df6 = df6.drop(columns=[c for c in df6 if c[-len('.delete'):] == '.delete'], axis=1)
print(f"df6:\n{df6}\n")
输出:
df1:
Date Val0 Val1
0 2020-09-29 13:22:57 char1 5.34
1 2020-09-29 13:23:12 char2 4.50
2 2020-09-29 13:23:44 char3 NaN
3 2020-09-29 13:24:01 char4 24.00
df2:
Date Val0 Val1
0 2020-09-29 13:22:58 char6 NaN
1 2020-09-29 13:23:12 char4 89.77
2 2020-09-29 13:23:45 NaN
3 2020-09-29 13:24:01 char4 24.00
df_minus:
Date.delete Val0.delete Val1.diff
0 2020-09-29 13:22:57 char1 NaN
1 2020-09-29 13:23:12 char2 -85.27
2 2020-09-29 13:23:44 char3 NaN
3 2020-09-29 13:24:01 char4 0.00
df6:
Date Date.2 Val0 Val0.2 Val1 Val1.2 Val1.diff
0 2020-09-29 13:22:57 2020-09-29 13:22:58 char1 char6 5.34 NaN NaN
1 2020-09-29 13:23:12 2020-09-29 13:23:12 char2 char4 4.50 89.77 -85.27
2 2020-09-29 13:23:44 2020-09-29 13:23:45 char3 NaN NaN NaN
3 2020-09-29 13:24:01 2020-09-29 13:24:01 char4 char4 24.00 24.00 0.00
我有 2 个具有相同列和行号的数据框,其中一些数据框的列是日期(每个数据框 1 个),其他的是浮点数和存储字符串的对象。
让我们以下面的 df1 为例进行简化(我的实际数据框有数百列):
Date Val0 Val1
0 2020-09-29 13:22:57 char1 5.34
1 2020-09-29 13:23:12 char2 4.5
2 2020-09-29 13:23:44 char3 Nan
3 2020-09-29 13:24:01 char4 24
val0
在那个例子中是一个对象
df2
看起来像:
Date Val0 Val1
0 2020-09-29 13:22:58 char6 Nan
1 2020-09-29 13:23:12 char4 89.77
2 2020-09-29 13:23:45 Nan
3 2020-09-29 13:24:01 char4 24
预计
Date Date Val0 Val0 Val1 Val1 Val1
0 2020-09-29 13:22:57 2020-09-29 13:22:58 char1 char6 5.34 Nan 5.34
1 2020-09-29 13:23:12 2020-09-29 13:23:12 char2 char4 4.5 89.77 -85.27
2 2020-09-29 13:23:44 2020-09-29 13:23:45 char3 Nan Nan Nan
3 2020-09-29 13:24:01 2020-09-29 13:24:01 char4 char4 24 24 0
正如我们所看到的,浮点数被扣除了,我们有一个新的列有差异,而具有相同列的对象现在是 'next to one another'
我确实意识到使用相同的列名可能不是方法,例如,如果我们想删除一个或 pandas 默认添加的 .2
,对我来说是列名在这个阶段,它们可以是任何东西,因为它们已按照演示对齐,并且在写入 excel 时仍会帮助我进行下一步,这仅合并行名称,例如我们有一个
单元格下面有 2 列,同时它也是 val1
的 1 行名称和下面的 3 列。
My code and approach:
我想去掉我不能扣除的东西,在本例中是 val0
,所以我从复制的数据框中删除了 df1
和 df2
的那一列,然后扣除了结果 dfs 给了我 val1 的最后一列和日期的扣除以防万一我想要它。然后连接 df1
和 df_2
看起来像下面对应 df_6
:
df_minus = df_2 - df
df5 = pd.concat([df_2, df], axis=1)
df_6 = df5[list(sum(zip(df_2.columns, df.columns), ()))]
print(df_6)
Date Date Val0 Val0 Val1 Val1
0 2020-09-29 13:22:57 2020-09-29 13:22:58 char1 char6 5.34 Nan
1 2020-09-29 13:23:12 2020-09-29 13:23:12 char2 char4 4.5 89.77
2 2020-09-29 13:23:44 2020-09-29 13:23:45 char3 Nan Nan
3 2020-09-29 13:24:01 2020-09-29 13:24:01 char4 char4 24 24
我的方法确实解决了列是对象的问题,但是对于浮点数,我虽然以某种方式使用 df_minus 但找不到 way.Some 可能认为我应该简单地从中获取该列df_minus
并将其添加到 df_6
但请记住,我的实际数据有数百列,所以这不是一个选项。
这是一种方法,应该可以让您实现我认为您正在尝试做的事情。
我们确定减法运算对其有意义的数字列,然后进行减法并使用结果更新 df_minus
,其中一个输入数据帧的副本。然后,我们通过为减法结果附加“.diff”或为减法结果附加“.delete”(标记为将来删除)来重命名 df2
中的列,方法是附加后缀“.2”和 df_minus
中的列所有其他列。
然后我们使用您的列排序逻辑,但使用 3 个数据框而不是 2 个,因此结果中有 df1
、df2
和 df_minus
。最后,我们删除来自 df_minus
.
import pandas as pd
import numpy as np
df1 = pd.DataFrame([
{'Date':'2020-09-29 13:22:57','Val0':'char1','Val1':5.34},
{'Date':'2020-09-29 13:23:12','Val0':'char2','Val1':4.5},
{'Date':'2020-09-29 13:23:44','Val0':'char3','Val1':np.NaN},
{'Date':'2020-09-29 13:24:01','Val0':'char4','Val1':24}
])
df2 = pd.DataFrame([
{'Date':'2020-09-29 13:22:58','Val0':'char6','Val1':np.NaN},
{'Date':'2020-09-29 13:23:12','Val0':'char4','Val1':89.77},
{'Date':'2020-09-29 13:23:45','Val0':'', 'Val1':np.NaN},
{'Date':'2020-09-29 13:24:01','Val0':'char4','Val1':24}
])
print(f"df1:\n{df1}\n")
print(f"df2:\n{df2}\n")
dfNumericCols = set(c for c in df1.columns if isinstance(df1.loc[0,c], (float,int)))
df_minus = df1.copy(deep=True)
df_minus[list(dfNumericCols)] = df1[list(dfNumericCols)] - df2[list(dfNumericCols)]
df_minus.rename(columns={c:c+'.diff' if c in dfNumericCols else c+'.delete' for c in df_minus.columns}, inplace=True)
print(f"df_minus:\n{df_minus}\n")
df2.rename(columns={c:c+'.2' for c in df2.columns}, inplace=True)
df5 = pd.concat([df1, df2, df_minus], axis=1)
df6 = df5[list(sum(zip(df1.columns, df2.columns, df_minus.columns), ()))]
df6 = df6.drop(columns=[c for c in df6 if c[-len('.delete'):] == '.delete'], axis=1)
print(f"df6:\n{df6}\n")
输出:
df1:
Date Val0 Val1
0 2020-09-29 13:22:57 char1 5.34
1 2020-09-29 13:23:12 char2 4.50
2 2020-09-29 13:23:44 char3 NaN
3 2020-09-29 13:24:01 char4 24.00
df2:
Date Val0 Val1
0 2020-09-29 13:22:58 char6 NaN
1 2020-09-29 13:23:12 char4 89.77
2 2020-09-29 13:23:45 NaN
3 2020-09-29 13:24:01 char4 24.00
df_minus:
Date.delete Val0.delete Val1.diff
0 2020-09-29 13:22:57 char1 NaN
1 2020-09-29 13:23:12 char2 -85.27
2 2020-09-29 13:23:44 char3 NaN
3 2020-09-29 13:24:01 char4 0.00
df6:
Date Date.2 Val0 Val0.2 Val1 Val1.2 Val1.diff
0 2020-09-29 13:22:57 2020-09-29 13:22:58 char1 char6 5.34 NaN NaN
1 2020-09-29 13:23:12 2020-09-29 13:23:12 char2 char4 4.50 89.77 -85.27
2 2020-09-29 13:23:44 2020-09-29 13:23:45 char3 NaN NaN NaN
3 2020-09-29 13:24:01 2020-09-29 13:24:01 char4 char4 24.00 24.00 0.00