使用来自另一个 Dataframe 的公共索引值来完成一个空的 DataFrame

Posted

技术标签:

【中文标题】使用来自另一个 Dataframe 的公共索引值来完成一个空的 DataFrame【英文标题】:fulfill an empty dataframe with common index values from another Daframe 【发布时间】:2016-08-15 00:00:54 【问题描述】:

我有一个 daframe,其周期为 1 个月,频率为 1 秒。

记录之间的时间步长并不总是1秒的问题。

time                c1  c2
2013-01-01 00:00:01 5   3
2013-01-01 00:00:03 7   2
2013-01-01 00:00:04 1   5
2013-01-01 00:00:05 4   3
2013-01-01 00:00:06 5   6
2013-01-01 00:00:09 4   2
2013-01-01 00:00:10 7   8

然后我想创建一个具有相同列的空数据框,并在整个期间进行更正。这意味着一个月的记录数与秒数一样多。这个空数据框原则上是用 nan 值实现的:

time                c1  c2
2013-01-01 00:00:01 nan nan
2013-01-01 00:00:02 nan nan
2013-01-01 00:00:03 nan nan
2013-01-01 00:00:04 nan nan
2013-01-01 00:00:05 nan nan
2013-01-01 00:00:06 nan nan
2013-01-01 00:00:07 nan nan
2013-01-01 00:00:08 nan nan
2013-01-01 00:00:09 nan nan
2013-01-01 00:00:10 nan nan

然后比较两者,并用我的第一个数据框的公共行填充空行。不常见的应该保留 nan 值。

time                c1  c2
2013-01-01 00:00:01 5   3
2013-01-01 00:00:02 nan nan
2013-01-01 00:00:03 7   2
2013-01-01 00:00:04 1   5
2013-01-01 00:00:05 4   3
2013-01-01 00:00:06 5   6
2013-01-01 00:00:07 nan nan
2013-01-01 00:00:08 nan nan
2013-01-01 00:00:09 4   2
2013-01-01 00:00:10 7   8

我的尝试:

#Read from a file the first dataframe
df1=pd.read_table(fin,parse_dates=0],names=ch,index_col=0,header=0,decimal='.',skiprows=c)
#create an empty dataframe 
N=86400 * 31#seconds per month
index=pd.date_range(df1.index[0], periods=N-1, freq='1s')
df2=pd.DataFrame(index=index, columns=df1.columns)

现在我尝试使用 merge 或 concat 但没有预期的结果:

df2.merge(df1, how='outer')
pd.concat([df2,df1], axis=0, join='outer')

【问题讨论】:

【参考方案1】:

我认为您不需要第二个数据框。如果您在没有fill_method 的情况下调用resample,它将为缺少的句点存储NaNs:

df.resample("s").max()
Out[62]: 
                      c1   c2
time                         
2013-01-01 00:00:01  5.0  3.0
2013-01-01 00:00:02  NaN  NaN
2013-01-01 00:00:03  7.0  2.0
2013-01-01 00:00:04  1.0  5.0
2013-01-01 00:00:05  4.0  3.0
2013-01-01 00:00:06  5.0  6.0
2013-01-01 00:00:07  NaN  NaN
2013-01-01 00:00:08  NaN  NaN
2013-01-01 00:00:09  4.0  2.0
2013-01-01 00:00:10  7.0  8.0

max() 这里只是一个任意方法,因此它返回一个数据帧。假设您没有重复项,您可以将其替换为均值、最小值等。如果您有重复项,它们将由该函数聚合。

正如 Paul H 在 cmets 中建议的那样,您可以使用 df.resample("s").asfreq() 而无需任何聚合。它跳过了不必要的聚合步骤,因此它可能更有效。如果索引中有重复值,则会引发错误。

【讨论】:

我想保持常用值不变,而不是重新采样 @gis20 因为频率是相同的,你应该得到它们的共同值。有什么区别吗? df.resample("s").asfreq() 将盲目地对数据进行上采样而不应用任何类型的归约函数/【参考方案2】:

您需要reindex 数据框。

import pandas
df = pandas.read_table(filename, **options)
N = 86400 * 31 #seconds per month
dates = pandas.date_range(df.index[0], periods=N-1, freq='1s')
df = df.reindex(dates)

这是一个可重现的演示:

df = pandas.DataFrame(
    data='A': range(0, 10), 'B': range(0, 20, 2),
    index=pandas.date_range('2012-01-01', freq='2s', periods=10)
).reindex(pandas.date_range('2012-01-01', freq='1s', periods=25))

print(df)

                       A     B
2012-01-01 00:00:00  0.0   0.0
2012-01-01 00:00:01  NaN   NaN
2012-01-01 00:00:02  1.0   2.0
2012-01-01 00:00:03  NaN   NaN
2012-01-01 00:00:04  2.0   4.0
2012-01-01 00:00:05  NaN   NaN
2012-01-01 00:00:06  3.0   6.0
2012-01-01 00:00:07  NaN   NaN
2012-01-01 00:00:08  4.0   8.0
2012-01-01 00:00:09  NaN   NaN
2012-01-01 00:00:10  5.0  10.0
2012-01-01 00:00:11  NaN   NaN
2012-01-01 00:00:12  6.0  12.0
2012-01-01 00:00:13  NaN   NaN
2012-01-01 00:00:14  7.0  14.0
2012-01-01 00:00:15  NaN   NaN
2012-01-01 00:00:16  8.0  16.0
2012-01-01 00:00:17  NaN   NaN
2012-01-01 00:00:18  9.0  18.0
2012-01-01 00:00:19  NaN   NaN
2012-01-01 00:00:20  NaN   NaN
2012-01-01 00:00:21  NaN   NaN
2012-01-01 00:00:22  NaN   NaN
2012-01-01 00:00:23  NaN   NaN
2012-01-01 00:00:24  NaN   NaN

【讨论】:

不起作用。*** ValueError: cannot reindex from a duplicate axis @gis20 查看我的编辑。如果没有可重现的示例来证明您的问题,我将无法再为您提供帮助。【参考方案3】:

如果你已经在“nan”数据框中设置了索引,我想你应该可以只使用loc。 Indexing 是使用 Pandas 时要掌握的非常重要的东西。它将为您节省大量时间,使您的代码更简洁,并且可以真正提高您的性能。

但请注意,索引和列必须相同才能使下面的技巧正常工作。

>>> import pandas as pd
>>> import numpy as np

>>> df1 = pd.DataFrame(np.random.rand(10, 3), columns=['A', 'B', 'C'])
>>> df1
          A         B         C
0  0.171502  0.258416  0.118326
1  0.215456  0.462122  0.858173
2  0.373549  0.946400  0.579845
3  0.606289  0.289552  0.473658
4  0.885899  0.783747  0.089975
5  0.674208  0.639710  0.105642
6  0.404775  0.541389  0.268101
7  0.374609  0.693916  0.743575
8  0.074773  0.150072  0.135555
9  0.230431  0.202417  0.466538

>>> df2 = pd.DataFrame(np.nan, index=range(15), columns=['A', 'B', 'C'])
>>> df2
     A   B   C
0  NaN NaN NaN
1  NaN NaN NaN
2  NaN NaN NaN
3  NaN NaN NaN
4  NaN NaN NaN
5  NaN NaN NaN
6  NaN NaN NaN
7  NaN NaN NaN
8  NaN NaN NaN
9  NaN NaN NaN
10 NaN NaN NaN
11 NaN NaN NaN
12 NaN NaN NaN
13 NaN NaN NaN
14 NaN NaN NaN

>>> df2.loc[df1.index] = df1    # This is where the magic happens
>>> df2
           A         B         C
0   0.171502  0.258416  0.118326
1   0.215456  0.462122  0.858173
2   0.373549  0.946400  0.579845
3   0.606289  0.289552  0.473658
4   0.885899  0.783747  0.089975
5   0.674208  0.639710  0.105642
6   0.404775  0.541389  0.268101
7   0.374609  0.693916  0.743575
8   0.074773  0.150072  0.135555
9   0.230431  0.202417  0.466538
10       NaN       NaN       NaN
11       NaN       NaN       NaN
12       NaN       NaN       NaN
13       NaN       NaN       NaN
14       NaN       NaN       NaN

【讨论】:

以上是关于使用来自另一个 Dataframe 的公共索引值来完成一个空的 DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

如何使用来自另一个数据帧的索引创建考拉数据帧?

在 Python 中使用来自 Dataframe 索引的数据创建列表

dataframe按值(非索引)查找多行

在 Scala 中使用来自另一个没有数组列的 DataFrame 的数组类型列创建 Spark DataFrame 的有效方法是啥?

从另一个 Dataframe 中的一个 Dataframe 中查找元素并返回其索引的快速方法

python - “将重新索引布尔系列键以匹配DataFrame索引。来自ipykernel导入kernelapp作为app“