Python 按特定顺序从两个dfs中获取列并创建一个新的df

Python 按特定顺序从两个dfs中获取列并创建一个新的df,python,pandas,Python,Pandas,我有两个大数据帧。其中一个包含2020年1月的一组信息(f2020)。另一个数据帧(f2021)包含相同的信息,但用于2021年1月。数据帧相等,但值不同。(行数/列数、键名等相同) 我使用了一个事实,即它们是euqal来循环f2021中的每个项目,并从f2020中减去相同的项目。结果作为键为'diff_key'的列添加到f2021中 我创建了一个示例,这是在进行任何计算之前: f2021 = pd.DataFrame({'C3456R_[Ah]': {0: 2.5, 1: 4.3, 2:

我有两个大数据帧。其中一个包含2020年1月的一组信息(f2020)。另一个数据帧(f2021)包含相同的信息,但用于2021年1月。数据帧相等,但值不同。(行数/列数、键名等相同)

我使用了一个事实,即它们是euqal来循环f2021中的每个项目,并从f2020中减去相同的项目。结果作为键为'diff_key'的列添加到f2021中

我创建了一个示例,这是在进行任何计算之前:

f2021 = pd.DataFrame({'C3456R_[Ah]': {0: 2.5,
  1: 4.3, 2: 5.9},
 'C8734_[Ah]': {0: 1.9,
  1: 2.3, 2: 3.9},
 'ts': {0: pd.Timestamp('2020-01-01 02:00:00'),
  1: pd.Timestamp('2020-01-01 03:00:00'),
  2: pd.Timestamp('2020-01-01 04:00:00')}})
然后我用f2020中的值进行计算,得到一个结果f2021,如下所示:

f2021 = pd.DataFrame({'C3456R_[Ah]': {0: 2.5,
  1: 4.3, 2: 5.9},
 'C8734_[Ah]': {0: 1.9,
  1: 2.3, 2: 3.9},
 'ts': {0: pd.Timestamp('2020-01-01 02:00:00'),
  1: pd.Timestamp('2020-01-01 03:00:00'),
  2: pd.Timestamp('2020-01-01 04:00:00')},
  'diff_C3456R_[Ah]': {0: 0.1,
  1: 0.7, 2: 0.2},
 'diff_C8734_[Ah]': {0: 0.1,
  1: 1.2, 2: 2.2}})
现在,我想创建一个新的df,它应该为f2021和f2020中的同一个键使用两个原始列,添加一个sufix(_2020和_2021),然后为该键使用“diff”列,用于所有键。必须对列进行排序,以便顺序如下:

‘C3456R[Ah]2021’、‘C3456R[Ah]2020’、‘差异C3456R[Ah]、‘C8734[Ah]2021、C8734[Ah]2020、差异C8734[Ah]。。。等等

新df中的键顺序应遵循f2021中原始键的顺序

我试着通过创建一个列表来解决这个问题,这个列表的顺序是我想要的,通过循环不同的if语句,并在列表中添加内容等等。我想我可以通过合并来解决这个问题。首先,为两个帧中的所有关键帧提供后缀。但这似乎是解决这个问题的一个沉重的方法,而且比人们想象的要困难


这是一种顺利的方法吗?

根据您的评论,以下是我认为具有形状的真实测试数据帧(744361):

为了清晰起见,我将把事情分成不同的步骤,但是如果您愿意,可以删除一些中间步骤

因为您保证数据帧是完全相同的形状/列,所以您可以直接减去数据帧并将其连接起来

首先,对列名进行一些操作,现在跳过
ts
列:

base_cols = [c for c in f2021.columns if c != 'ts']
cols_2020 = [f"{c}_2020" for c in base_cols]
cols_2021 = [f"{c}_2021" for c in base_cols]
cols_diff = [f"{c}_diff" for c in base_cols]
现在制作一个类似时间戳的列,以便以后使用。您可以根据自己的喜好处理此问题,但这些将是字符串:

ts = f2021['ts'].dt.strftime("%m-%d %H:%M:%S").to_frame('ts')
执行减法,但删除原始时间戳:

tmp2020 = f2020.drop(columns='ts')
tmp2021 = f2021.drop(columns='ts')
diff = tmp2021.sub(tmp2020)
然后担心列名:

tmp2020.columns = cols_2020
tmp2021.columns = cols_2021
diff.columns = cols_diff
使用
pd.concat
将它们组合在一起(使用前面的类似时间戳的列)。这非常快:

result = pd.concat([ts, tmp2021, tmp2020, diff], axis=1)
最后,对列重新排序:

import itertools
new_cols = list(itertools.chain.from_iterable(zip(cols_2021, cols_2020, cols_diff)))
result = result[['ts'] + new_cols]

print(result.shape)
(744, 1081)

print(result.columns[:6])
Index(['ts', 'Col_0_2021', 'Col_0_2020', 'Col_0_diff', 'Col_1_2021',
       'Col_1_2020'],
      dtype='object')

谢谢,但是dfs有360个不同键的COL。我需要通过循环键来解决这个问题,否则这会消耗我的时间预算。好吧,我现在更明白了。我会修改它。
import itertools
new_cols = list(itertools.chain.from_iterable(zip(cols_2021, cols_2020, cols_diff)))
result = result[['ts'] + new_cols]

print(result.shape)
(744, 1081)

print(result.columns[:6])
Index(['ts', 'Col_0_2021', 'Col_0_2020', 'Col_0_diff', 'Col_1_2021',
       'Col_1_2020'],
      dtype='object')