Python 熊猫:基于布尔列表/dict替换数据帧列

Python 熊猫:基于布尔列表/dict替换数据帧列,python,pandas,Python,Pandas,我有两个pandas数据帧,我想合并在一起,但不是以我在我能找到的示例中看到的方式。我有一组“旧”数据和一组“新”数据,用于两个形状相同且具有相同列名的数据帧。我做了一些分析,确定需要创建第三个数据集,从“旧”数据中提取一些列,从“新”数据中提取一些列。例如,假设我有两个数据集: df_old = pd.DataFrame(np.zeros([5,5]),columns=list('ABCDE')) df_new = pd.DataFrame(np.ones([5,5]),columns=lis

我有两个pandas数据帧,我想合并在一起,但不是以我在我能找到的示例中看到的方式。我有一组“旧”数据和一组“新”数据,用于两个形状相同且具有相同列名的数据帧。我做了一些分析,确定需要创建第三个数据集,从“旧”数据中提取一些列,从“新”数据中提取一些列。例如,假设我有两个数据集:

df_old = pd.DataFrame(np.zeros([5,5]),columns=list('ABCDE'))
df_new = pd.DataFrame(np.ones([5,5]),columns=list('ABCDE'))
简单来说就是:

     A    B    C    D    E
0  0.0  0.0  0.0  0.0  0.0
1  0.0  0.0  0.0  0.0  0.0
2  0.0  0.0  0.0  0.0  0.0
3  0.0  0.0  0.0  0.0  0.0
4  0.0  0.0  0.0  0.0  0.0

我做了一些分析,发现我想替换列
B
D
。我可以这样循环:

replace = dict(A=False,B=True,C=False,D=True,E=False)
df = pd.DataFrame({})
for k,v in sorted(replace.items()):
    df[k] = df_new[k] if v else df_old[k]
这为我提供了所需的数据:

     A    B    C    D    E
0  0.0  1.0  0.0  1.0  0.0
1  0.0  1.0  0.0  1.0  0.0
2  0.0  1.0  0.0  1.0  0.0
3  0.0  1.0  0.0  1.0  0.0
4  0.0  1.0  0.0  1.0  0.0
但是,老实说,这似乎有点笨重,我想有更好的方法利用熊猫来做到这一点。另外,我想保留我的列的顺序,这些列可能不像这个示例数据集那样按字母顺序排列,因此对字典进行排序可能不是一个好办法,尽管如果需要,我可能会从数据集中提取列名


有没有更好的方法使用一些合并功能来实现这一点?

只需分配所需的新列:

df_old['B'] = df_new['B']
df_old['D'] = df_new['D']
或作为一行:

df_changes = df_old.copy()
df_changes[['B', 'D']] = df_new[['B', 'D']]

最基本的方法是过滤布尔dict,然后直接赋值

to_rep = [k for k in replace if replace[k]]
df_old[to_rep] = df_new[to_rep]
如果您想保留旧的数据帧,可以使用

正如Nickil所提到的,
assign()
显然不会在传递dict时保留参数顺序。但是,为了可预测,它会在数据帧末尾按字母顺序插入指定的列

演示

>>> df_old.assign(**{k: df_new[k] for k in replace if replace[k]})

     A    B    C    D    E
0  0.0  1.0  0.0  1.0  0.0
1  0.0  1.0  0.0  1.0  0.0
2  0.0  1.0  0.0  1.0  0.0
3  0.0  1.0  0.0  1.0  0.0
4  0.0  1.0  0.0  1.0  0.0

基于“Boolean
list/dict
”进行替换如果他能够构造
replace=dict(A=False,B=True,C=False,D=True,E=False)
,他也应该能够构造
['B','D']
,有没有办法在这个基础上创建一个新的数据帧,而不是覆盖旧的数据集?我知道我可以复制其他的一个,但我不认为它最终会和我已经做的有太大的不同。我想可能没有更好的方法了。以前做过df_old.copy()。这正是我尝试做这件事时所处的位置。我想尝试保留另外两个数据帧,这就是我创建上面的新数据帧的原因。我希望有一个pandas函数来实现这一点,但可能没有。请注意,
assign
并没有保留顺序,因为它基本上保存了一个字典。但是,它会按字典排序的顺序返回列名。@NickilMaveli是的,这绝对值得注意:)可能会在我的答案中添加一个提示。@NickilMaveli感谢您注意到这一点。当我这样做时,我拥有的列将已经存在于这两个数据集中,并且应该覆盖它们。如果它覆盖了一个现有的列,你是说它不一定会把它放在同一个地方吗?这也许没关系,但我只是好奇而已。我自己来看看。是的,如果列名不按字母顺序排序,情况就是这样。正如我之前所说,
assign
将简单地按排序顺序返回这些值。您仍然可以通过在末尾链接
.reindex(columns=df_old.columns)
来保持原始顺序。
df_old.assign(**{k: df_new[k] for k in replace if replace[k]})
>>> df_old.assign(**{k: df_new[k] for k in replace if replace[k]})

     A    B    C    D    E
0  0.0  1.0  0.0  1.0  0.0
1  0.0  1.0  0.0  1.0  0.0
2  0.0  1.0  0.0  1.0  0.0
3  0.0  1.0  0.0  1.0  0.0
4  0.0  1.0  0.0  1.0  0.0