如何在两个单独的 Pandas DataFrame 中的所有值之间进行插值?
How to Interpolate between all Values in Two Separate Pandas DataFrames?
假设您有两个 Pandas DataFrame,一个包含 2020 年的数据,另一个包含 2030 年的数据。两个 DataFrame 具有相同的形状、列名,并且只包含数值。为简单起见,我们将按如下方式创建它们:
twenty = pd.DataFrame({'A':[1,1,1], 'B':[3,3,3]})
thirty = pd.DataFrame({'A':[3,3,3], 'B':[7,7,7]})
现在,目标是对这些 DataFrame 中的所有值执行线性插值,以获得 2025 年(或我们 select 的任何年份)的新 DataFrame。因此,我们希望在每对值集之间进行插值,例如 twenty['A'][0]
和 thirty['A'][0]
。如果我们在目标年 2025 年这样做,结果应该是:
twentyfive = pd.DataFrame({'A':[2,2,2],'B':[5,5,5]})
我尝试使用 np.interp
;但是,据我所知,这实际上是为了对给定的(奇异的)数组进行插值。我已经使用更暴力的方法解决了这个问题,即融化 DataFrame、添加年份列、将它们合并在一起,然后使用插值创建一个新列。有点乱,啰嗦。
我觉得必须有一种更直接(和优化)的方式来执行此任务。感谢任何帮助。
你可以尝试直接取平均值,如果两者的形状相同
(thirty + twenty)/2
输出:
A B
0 2 5
1 2 5
2 2 5
编辑:如果数据框的形状不相等,您可以尝试合并内部连接和分组列以获取插值平均值。
df = pd.merge(twenty,thirty, left_index=True, right_index=True, how='inner').rename(columns=lambda x: x.split('_')[0])
df.T.groupby(df.T.index).mean().T
输出:
A B
0 2 5
1 2 5
2 2 5
您可以 concat
巧妙地使用键(将它们命名为整数),然后 groupby
允许您插入所有内容:
import pandas as pd
df = pd.concat([twenty, thirty], keys=[20,30], axis=1)
s = (df.groupby(df.columns.get_level_values(1), axis=1)
.apply(lambda x: x.T.reset_index(1, drop=True).reindex(np.arange(20,31)).interpolate())).T
20 21 22 23 24 25 26 27 28 29 30
A 0 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0
1 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0
2 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0
B 0 3.0 3.4 3.8 4.2 4.6 5.0 5.4 5.8 6.2 6.6 7.0
1 3.0 3.4 3.8 4.2 4.6 5.0 5.4 5.8 6.2 6.6 7.0
2 3.0 3.4 3.8 4.2 4.6 5.0 5.4 5.8 6.2 6.6 7.0
现在如果你只关心 25:
s[25].unstack(0)
A B
0 2.0 5.0
1 2.0 5.0
2 2.0 5.0
假设您有两个 Pandas DataFrame,一个包含 2020 年的数据,另一个包含 2030 年的数据。两个 DataFrame 具有相同的形状、列名,并且只包含数值。为简单起见,我们将按如下方式创建它们:
twenty = pd.DataFrame({'A':[1,1,1], 'B':[3,3,3]})
thirty = pd.DataFrame({'A':[3,3,3], 'B':[7,7,7]})
现在,目标是对这些 DataFrame 中的所有值执行线性插值,以获得 2025 年(或我们 select 的任何年份)的新 DataFrame。因此,我们希望在每对值集之间进行插值,例如 twenty['A'][0]
和 thirty['A'][0]
。如果我们在目标年 2025 年这样做,结果应该是:
twentyfive = pd.DataFrame({'A':[2,2,2],'B':[5,5,5]})
我尝试使用 np.interp
;但是,据我所知,这实际上是为了对给定的(奇异的)数组进行插值。我已经使用更暴力的方法解决了这个问题,即融化 DataFrame、添加年份列、将它们合并在一起,然后使用插值创建一个新列。有点乱,啰嗦。
我觉得必须有一种更直接(和优化)的方式来执行此任务。感谢任何帮助。
你可以尝试直接取平均值,如果两者的形状相同
(thirty + twenty)/2
输出:
A B
0 2 5
1 2 5
2 2 5
编辑:如果数据框的形状不相等,您可以尝试合并内部连接和分组列以获取插值平均值。
df = pd.merge(twenty,thirty, left_index=True, right_index=True, how='inner').rename(columns=lambda x: x.split('_')[0])
df.T.groupby(df.T.index).mean().T
输出:
A B
0 2 5
1 2 5
2 2 5
您可以 concat
巧妙地使用键(将它们命名为整数),然后 groupby
允许您插入所有内容:
import pandas as pd
df = pd.concat([twenty, thirty], keys=[20,30], axis=1)
s = (df.groupby(df.columns.get_level_values(1), axis=1)
.apply(lambda x: x.T.reset_index(1, drop=True).reindex(np.arange(20,31)).interpolate())).T
20 21 22 23 24 25 26 27 28 29 30
A 0 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0
1 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0
2 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0
B 0 3.0 3.4 3.8 4.2 4.6 5.0 5.4 5.8 6.2 6.6 7.0
1 3.0 3.4 3.8 4.2 4.6 5.0 5.4 5.8 6.2 6.6 7.0
2 3.0 3.4 3.8 4.2 4.6 5.0 5.4 5.8 6.2 6.6 7.0
现在如果你只关心 25:
s[25].unstack(0)
A B
0 2.0 5.0
1 2.0 5.0
2 2.0 5.0