基于索引(时间序列)合并 Pandas 行

3
我使用了 Pandas.append() 方法,通过索引(日期)从多个Pandas timeseries 中添加列。然而,与其将所有公共日期的数据合并为一行,数据看起来像这样:
sve2_all.sort(inplace=True)
print sve2_all['20000101':'20000104']



Hgtot ng/l     Q l/s  DOC_mg/L  Flow_mm/day  MeHg ng/l Site  \
2000-01-01          NaN       NaN       NaN         0.18        NaN  NaN   
2000-01-01          NaN  0.613234       NaN          NaN        NaN  SVE   
2000-01-02          NaN       NaN       NaN         0.18        NaN  NaN   
2000-01-02          NaN  0.614410       NaN          NaN        NaN  SVE   
2000-01-03          NaN       NaN       NaN          NaN        NaN    2   
2000-01-03          NaN  0.617371       NaN          NaN        NaN  SVE   
2000-01-03          NaN       NaN       NaN          NaN        NaN  NaN   
2000-01-03          NaN       NaN       NaN         0.18        NaN  NaN   
2000-01-04          NaN  0.627733       NaN          NaN        NaN  SVE   
2000-01-04          NaN       NaN       NaN         0.18        NaN  NaN   

            TOC_filt.TOC  TOC_unfilt.TOC  Temp oC  pH  
2000-01-01           NaN             NaN      NaN NaN  
2000-01-01           NaN             NaN -12.6117 NaN  
2000-01-02           NaN             NaN      NaN NaN  
2000-01-02           NaN             NaN  -2.3901 NaN  
2000-01-03           NaN        8.224648      NaN NaN  
2000-01-03           NaN             NaN  -5.0064 NaN  
2000-01-03           NaN             NaN      NaN NaN  
2000-01-03           NaN             NaN      NaN NaN  
2000-01-04           NaN             NaN  -1.5868 NaN  
2000-01-04           NaN             NaN      NaN NaN  

[10 rows x 10 columns]

我曾尝试使用以下方法对这些数据进行按天重新采样:
sve2_all.resample('D', how='mean')

同时也可以使用以下方式按天分组:

sve2_all.groupby(sve2_all.index.map(lambda t: t.day))

然而,DataFrame 保持不变。我该如何将相同日期的行合并为一个日期?谢谢。 附加信息:我尝试使用Joris建议的pd.concat()(由于1作为轴参数会导致ValueError:cannot reindex from a duplicate axis,所以我必须传递0),而不是.append(),但生成的DataFrame.append()相同,是一个非均匀非单调时间序列。我认为索引是问题所在,但我不确定该怎么做才能修复它,我认为一些时间戳可能包含小时信息,而其他时间戳则没有,因此我尝试过在每个DataFrame上使用.resample('D',how='mean'),然后再使用.concat(),但没有任何区别。 解决方案:Joris的解决方案是正确的,我没有意识到.resample()不是就地操作。一旦.resample()被分配给一个新的DataFrame,Joris的建议提供了期望的结果。
1个回答

4
append 方法将行添加到另一个数据帧中,并不基于索引标签进行合并。如果要基于索引标签进行合并,您可以使用 concat 方法。
使用一个玩具示例:
In [14]: df1 = pd.DataFrame(np.random.randn(3,2), columns=list('AB'), index=pd.date_range('2000-01-01', periods=3))
In [15]: df1
Out[15]:
                   A         B
2000-01-01  1.532085 -1.338895
2000-01-02 -0.016784 -0.270698
2000-01-03 -1.680379  0.838287

In [16]: df2 = pd.DataFrame(np.random.randn(3,2), columns=list('CD'), index=pd.date_range('2000-01-01', periods=3))
In [17]: df2
Out[17]:
                   C         D
2000-01-01  0.375214 -0.812558
2000-01-02 -1.099848 -0.889941
2000-01-03  1.556383  0.870608

.append会追加行(并添加不在df1中的df2列,这里是这种情况):

In [18]: df1.append(df2)
Out[18]:
                   A         B         C         D
2000-01-01  1.532085 -1.338895       NaN       NaN
2000-01-02 -0.016784 -0.270698       NaN       NaN
2000-01-03 -1.680379  0.838287       NaN       NaN
2000-01-01       NaN       NaN  0.375214 -0.812558
2000-01-02       NaN       NaN -1.099848 -0.889941
2000-01-03       NaN       NaN  1.556383  0.870608

pd.concat()函数沿着其中一个索引轴将两个数据帧连接起来:

In [19]: pd.concat([df1, df2], axis=1)
Out[19]:
                   A         B         C         D
2000-01-01  1.532085 -1.338895  0.375214 -0.812558
2000-01-02 -0.016784 -0.270698 -1.099848 -0.889941
2000-01-03 -1.680379  0.838287  1.556383  0.870608

除此之外,resample 通常应该可以正常工作。

谢谢您的建议,我尝试使用pd.concat()(由于1作为轴参数会导致ValueError:cannot reindex from a duplicate axis,所以我必须传递0),但是生成的DataFrame.append()相同,都是非均匀非单调时间序列。我认为索引是问题所在,但我不确定从哪里开始查找,我认为某些时间戳可能包含小时信息,而其他时间戳则没有,这就是为什么我想要重新采样或按天分组的原因。您有任何建议/方法可以提供吗?再次感谢。 - Jason
你得到的错误是因为你的某个数据框中有重复的索引。正如错误所说,concat 无法处理这个问题。所以你应该删除这些重复的索引(然后重新采样应该是一个好方法),否则你可以使用合并:df1.merge(df2, left_index=True, right_index=True)。但如果你首先对两个数据框都做 .resample('D') 然后再用 concat([..], axis=1),你会得到什么错误? 因为这通常应该有效(通过重新采样,你不应该有重复值的问题)。 - joris
顺便提一下,你必须使用 axis=1,因为 axis=0 会沿着第一个轴连接两个数据框的行索引,这实际上与 append 相同(你想要连接列索引(axis=1),同时匹配行索引)。 - joris
1
请注意,resample 不是原地操作。因此,仅执行 df.resample('D') 是不够的,您需要重新分配它:df = df.resample('D')(当然,您也可以选择给它另外一个名称)。 - joris
1
顺便提一下,除非你明确指定,否则几乎没有pandas方法默认是inplace的,最好记住这一点。 - joris
显示剩余6条评论

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