使用具有相似索引的其他DataFrame的列创建pandas DataFrame

56

我有两个数据框 df1 和 df2,它们具有相同的列名 ['a','b','c'] 并由日期索引。 日期索引可能会有类似的值。 我想创建一个数据框 df3,其中只包含来自列 ['c'] 的数据,分别重命名为 'df1' 和 'df2',并具有正确的日期索引。我的问题是我不知道如何正确合并索引。

df1 = pd.DataFrame(np.random.randn(5,3), index=pd.date_range('01/02/2014',periods=5,freq='D'), columns=['a','b','c'] )
df2 = pd.DataFrame(np.random.randn(8,3), index=pd.date_range('01/01/2014',periods=8,freq='D'), columns=['a','b','c'] )
df1
                 a        b            c
2014-01-02   0.580550    0.480814    1.135899
2014-01-03  -1.961033    0.546013    1.093204
2014-01-04   2.063441   -0.627297    2.035373
2014-01-05   0.319570    0.058588    0.350060
2014-01-06   1.318068   -0.802209   -0.939962

df2
                 a        b            c
2014-01-01   0.772482    0.899337    0.808630
2014-01-02   0.518431   -1.582113    0.323425
2014-01-03   0.112109    1.056705   -1.355067
2014-01-04   0.767257   -2.311014    0.340701
2014-01-05   0.794281   -1.954858    0.200922
2014-01-06   0.156088    0.718658   -1.030077
2014-01-07   1.621059    0.106656   -0.472080
2014-01-08  -2.061138   -2.023157    0.257151

df3数据框应该具有以下形式:

df3
                 df1        df2
2014-01-01   NaN        0.808630
2014-01-02   1.135899   0.323425
2014-01-03   1.093204   -1.355067
2014-01-04   2.035373   0.340701
2014-01-05   0.350060   0.200922
2014-01-06   -0.939962  -1.030077
2014-01-07   NaN        -0.472080
2014-01-08   NaN        0.257151

但是,由于df2的日期索引更宽,df1列中存在NaN值。(在这个例子中,我会得到以下日期的NaN值:2014-01-01, 2014-01-07和2014-01-08

感谢您的帮助。

3个回答

95
您可以使用 concat
In [11]: pd.concat([df1['c'], df2['c']], axis=1, keys=['df1', 'df2'])
Out[11]: 
                 df1       df2
2014-01-01       NaN -0.978535
2014-01-02 -0.106510 -0.519239
2014-01-03 -0.846100 -0.313153
2014-01-04 -0.014253 -1.040702
2014-01-05  0.315156 -0.329967
2014-01-06 -0.510577 -0.940901
2014-01-07       NaN -0.024608
2014-01-08       NaN -1.791899

[8 rows x 2 columns]

axis参数决定了如何将DataFrames叠放在一起:

df1 = pd.DataFrame([1, 2, 3])
df2 = pd.DataFrame(['a', 'b', 'c'])

pd.concat([df1, df2], axis=0)
   0
0  1
1  2
2  3
0  a
1  b
2  c

pd.concat([df1, df2], axis=1)

   0  0
0  1  a
1  2  b
2  3  c

1
嗨,我在我的数据上进行了测试,但是出现了一个错误(AssertionError:索引长度与值不匹配)。唯一的原因似乎是它不起作用的原因是因为type(df1['c']) => pandas.core.series.TimeSeries,在我的数据中它是:pandas.core.series.Series。有什么想法吗? - user3153467
1
嗨,我已经找到问题了:我的数据中有一个重复的行索引,这导致了concat函数引发异常。 - user3153467
1
“keys”参数是用来做什么的?还有“axis”? - dopatraman
1
@dopatraman keys 会根据轴向(0 表示索引,1 表示列)来生成索引/列。在许多 pandas 方法中,您会发现 axis 参数具有相同的含义。 - Andy Hayden

8

嗯,我不确定合并是正确的方法。个人建议通过创建日期索引并使用列表推导式构建列来构建新的数据框。可能不是最符合Python风格的方法,但对我来说似乎行得通!

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.random.randn(5,3), index=pd.date_range('01/02/2014',periods=5,freq='D'), columns=['a','b','c'] )
df2 = pd.DataFrame(np.random.randn(8,3), index=pd.date_range('01/01/2014',periods=8,freq='D'), columns=['a','b','c'] )

# Create an index list from the set of dates in both data frames
Index = list(set(list(df1.index) + list(df2.index)))
Index.sort()

df3 = pd.DataFrame({'df1': [df1.loc[Date, 'c'] if Date in df1.index else np.nan for Date in Index],\
                'df2': [df2.loc[Date, 'c'] if Date in df2.index else np.nan for Date in Index],},\
                index = Index)

df3

0
你所要求的是join操作。 使用how参数,您可以定义如何处理唯一索引。 这里有一些文章,看起来对此点很有帮助。 在下面的示例中,为简单起见,我省略了美化(如重命名列)。

代码

import numpy as np
import pandas as pd
df1 = pd.DataFrame(np.random.randn(5,3), index=pd.date_range('01/02/2014',periods=5,freq='D'), columns=['a','b','c'] )
df2 = pd.DataFrame(np.random.randn(8,3), index=pd.date_range('01/01/2014',periods=8,freq='D'), columns=['a','b','c'] )

df3 = df1.join(df2, how='outer', lsuffix='_df1', rsuffix='_df2')
print(df3)

输出

               a_df1     b_df1     c_df1     a_df2     b_df2     c_df2
2014-01-01       NaN       NaN       NaN  0.109898  1.107033 -1.045376
2014-01-02  0.573754  0.169476 -0.580504 -0.664921 -0.364891 -1.215334
2014-01-03 -0.766361 -0.739894 -1.096252  0.962381 -0.860382 -0.703269
2014-01-04  0.083959 -0.123795 -1.405974  1.825832 -0.580343  0.923202
2014-01-05  1.019080 -0.086650  0.126950 -0.021402 -1.686640  0.870779
2014-01-06 -1.036227 -1.103963 -0.821523 -0.943848 -0.905348  0.430739
2014-01-07       NaN       NaN       NaN  0.312005  0.586585  1.531492
2014-01-08       NaN       NaN       NaN -0.077951 -1.189960  0.995123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接