使用 pd.concat 复制 pd.merge Pandas

Using pd.concat to replicate pd.merge Pandas

假设我有 3 个 df,如下所示:

df = pd.DataFrame({'Week': ['W1', 'W2', 'W3', 'W4', 'W5', 'W6', 'W7'], 'A': [34, 67, 92, 31, 90, 100, 101]})
df2 = pd.DataFrame({'Week': ['W4', 'W5', 'W6', 'W7', 'W8', 'W9', 'W10'], 'B': [75, np.nan, 53, 21, 94, 47, 88]})
df3 = pd.DataFrame({'Week': ['W12', 'W13', 'W14', 'W15', 'W16', 'W17', 'W18'], 'C': [25, 30, 40, 45, 46, 47, 48]})

通常,当我构建我的股票价格数据库时,我会使用 pd.merge 并使用非常有用的 on='Week'(在本例中)函数使用周列将数据框合并在一起。所以我的代码应该是这样的:

df = pd.merge(df, df2, on='Week', how='left')
df = pd.merge(df, df3, on='Week', how='left')

生成以下内容df

  Week    A     B   C
0   W1   34   NaN NaN
1   W2   67   NaN NaN
2   W3   92   NaN NaN
3   W4   31  75.0 NaN
4   W5   90   NaN NaN
5   W6  100  53.0 NaN
6   W7  101  21.0 NaN

这太完美了,我只想查看 W1 - W7 的数据,如果没有数据我只想要 NaN。

我被引导相信使用 pd.concatpd.merge 快得多,而且当我查看数百只股票时,这确实有助于减少构建我的 df。但是日期应该完全匹配当然非常重要,因此我一直在 pd.merge 中使用 on= 函数。

到目前为止,我无法弄清楚如何使用 pd.concat 复制此行为。有没有人有什么建议?到目前为止我尝试过的事情是这样的:

df = pd.concat([df, df2], sort=True).groupby('Week').mean()

但这会导致以下结果,甚至与我想要的还差得远:

          A     B
Week             
W1     34.0   NaN
W10     NaN  88.0
W2     67.0   NaN
W3     92.0   NaN
W4     31.0  75.0
W5     90.0   NaN
W6    100.0  53.0
W7    101.0  21.0
W8      NaN  94.0
W9      NaN  47.0

非常感谢任何帮助,干杯

编辑:

抱歉,澄清一下,我的预期输出是 df 一半,这个:

  Week    A     B   C
0   W1   34   NaN NaN
1   W2   67   NaN NaN
2   W3   92   NaN NaN
3   W4   31  75.0 NaN
4   W5   90   NaN NaN
5   W6  100  53.0 NaN
6   W7  101  21.0 NaN

你可以这样做:

concated = pd.concat([df, df2, df3], sort=False).groupby('Week').first()
result = concated[concated.index.isin(('W1', 'W2', 'W3', 'W4', 'W5', 'W6', 'W7'))]
print(result)

输出

          A     B   C
Week                 
W1     34.0   NaN NaN
W2     67.0   NaN NaN
W3     92.0   NaN NaN
W4     31.0  75.0 NaN
W5     90.0   NaN NaN
W6    100.0  53.0 NaN
W7    101.0  21.0 NaN

我只是链接合并方法,因为它更简洁,除非你有海量数据,否则速度差异并不明显。

df = df1.merge(df2, how='left').merge(df3, how='left')
print(df)

  Week    A     B   C
0   W1   34   NaN NaN
1   W2   67   NaN NaN
2   W3   92   NaN NaN
3   W4   31  75.0 NaN
4   W5   90   NaN NaN
5   W6  100  53.0 NaN
6   W7  101  21.0 NaN