【问题标题】:Resampling and merging data frame with python用python重采样和合并数据框
【发布时间】:2015-06-15 13:53:05
【问题描述】:

您好,我已经使用此代码创建了一个 dataFrame 字典

import os
import pandas 
import glob

path="G:\my_dir\*"
dataList={}

for files in glob.glob(path):
    dataList[files]=(read_csv(files,sep=";",index_col='Date'))

字典中存在的不同数据帧具有不同的时间样本。 dataFrame(A) 的一个例子是

Date               Volume   Value 
2014-01-04 06:00:02 6062   108000.0
2014-01-04 06:06:05 6062   107200.0
2014-01-04 06:12:07 6062   97400.0
2014-01-04 06:18:10 6062   99200.0
2014-01-04 06:24:12 6062   91300.0
2014-01-04 06:30:14 6062   84100.0
2014-01-04 06:36:17 6062   57000.0

dataFrame(B) 的例子是

Date                Volume Value 
2014-01-04 05:52:50  6062   4.7
2014-01-04 05:58:53  6062   4.7
2014-01-04 06:04:56  6062   4.9 
2014-01-04 06:10:58  6062   5.1
2014-01-04 06:17:01  6062   5.2
2014-01-04 06:23:03  6062   5.2
2014-01-04 06:29:05  6062   5.5
2014-01-04 06:35:08  6062   5.5

不同的数据框的行数不同。我想像这样将不同的数据框合并为一个:

    Data                 Volume       B               A               Value(DataframeN)
2014/04/01 05:52:50      6062        4.70            NaN
2014/04/01 05:58:53      6062        4.70            NaN
2014/04/01 06:04:56      6062        4.90            107465.51
2014/04/01 06:10:58      6062        5.10            100652.60
2014/04/01 06:17:01      6062        5.20            98899.57
2014/04/01 06:23:03      6062        5.20            92618.56
2014/04/01 06:29:05      6062        5.50            85301.73
2014/04/01 06:35:08      6062        5.50            61523.06

我在 Matlab 中使用命令很容易做到这一点

ts_A=timeseries(ValueA,datenum(DateA));
ts_B=timeseries(ValueB,datenum(DateB));
res_A=resample(ts_A,datenum(DateB));

我必须对几组 csv 文件执行此操作,因此我想使用 python 自动化该过程。

Tnx

【问题讨论】:

  • append()concat()。相当标准,请参阅文档。
  • concat() 我认为不会重新采样。这些值具有不同的时间采样,它们需要使用线性方法进行插值。
  • 你提供的关于你想要你的结果的例子并没有真正告诉我数据框最终应该是什么样子,你能发布一个更详细的例子吗?
  • 编写的代码实际上不会运行(您从不导入read_csv,并且您发布的DataFrames 与运行代码时应该得到的不匹配(Date 应该是索引,但您将其显示为列)。如果您发布您使用的确切代码会很有帮助。
  • @LorenzoBottaccioli 如果您按照编写的方式运行代码,您将得到NameError: name 'read_csv' is not defined

标签: python csv pandas resampling merging-data


【解决方案1】:

你可以concat两个DataFramesinterpolate,然后reindexDataFrame你想要的。

我假设我们有一定数量的DataFrames,其中Date 是所有DateTimeIndex。我将在此示例中使用两个,因为您在问题中使用了两个,但代码适用于任何数字。

df_a:

                     Volume   Value
Date                               
2014-01-04 06:00:02    6062  108000
2014-01-04 06:06:05    6062  107200
2014-01-04 06:12:07    6062   97400
2014-01-04 06:18:10    6062   99200
2014-01-04 06:24:12    6062   91300
2014-01-04 06:30:14    6062   84100
2014-01-04 06:36:17    6062   57000

df_b:

                     Volume  Value
Date                              
2014-01-04 05:52:50    6062    4.7
2014-01-04 05:58:53    6062    4.7
2014-01-04 06:04:56    6062    4.9
2014-01-04 06:10:58    6062    5.1
2014-01-04 06:17:01    6062    5.2
2014-01-04 06:23:03    6062    5.2
2014-01-04 06:29:05    6062    5.5
2014-01-04 06:35:08    6062    5.5

我将把这些放在dict 中作为示例。您将它们直接读入dict,因此您无需执行此步骤。我只想展示我的示例dict 的格式。 dict keys 没关系,任何有效的dict key 都可以:

dataList = {'a': df_a,
            'b': df_b}

这将我们带到您目前所在的位置,我的dataList 希望与您的格式相同。

您需要做的第一件事是合并DataFrames。我使用dictkeys 作为MultiIndex 列名,这样您就可以跟踪给定列的哪个实例来自哪个DataFrame。你可以这样做:

df = pd.concat(dataList.values(), axis=1, keys=dataList.keys())

这会给你一个像这样的DataFrame

                         a              b      
                    Volume   Value Volume Value
Date                                           
2014-01-04 05:52:50    NaN     NaN   6062   4.7
2014-01-04 05:58:53    NaN     NaN   6062   4.7
2014-01-04 06:00:02   6062  108000    NaN   NaN
2014-01-04 06:04:56    NaN     NaN   6062   4.9
2014-01-04 06:06:05   6062  107200    NaN   NaN
2014-01-04 06:10:58    NaN     NaN   6062   5.1
2014-01-04 06:12:07   6062   97400    NaN   NaN
2014-01-04 06:17:01    NaN     NaN   6062   5.2
2014-01-04 06:18:10   6062   99200    NaN   NaN
2014-01-04 06:23:03    NaN     NaN   6062   5.2
2014-01-04 06:24:12   6062   91300    NaN   NaN
2014-01-04 06:29:05    NaN     NaN   6062   5.5
2014-01-04 06:30:14   6062   84100    NaN   NaN
2014-01-04 06:35:08    NaN     NaN   6062   5.5
2014-01-04 06:36:17   6062   57000    NaN   NaN

接下来,您需要进行插值以填充缺失值。我使用 'time' mode 进行插值,因此它可以正确处理时间索引:

df = df.interpolate('time')

这会给你一个像这样的DataFrame

                         a                     b          
                    Volume          Value Volume     Value
Date                                                      
2014-01-04 05:52:50    NaN            NaN   6062  4.700000
2014-01-04 05:58:53    NaN            NaN   6062  4.700000
2014-01-04 06:00:02   6062  108000.000000   6062  4.738017
2014-01-04 06:04:56   6062  107352.066116   6062  4.900000
2014-01-04 06:06:05   6062  107200.000000   6062  4.938122
2014-01-04 06:10:58   6062   99267.955801   6062  5.100000
2014-01-04 06:12:07   6062   97400.000000   6062  5.119008
2014-01-04 06:17:01   6062   98857.851240   6062  5.200000
2014-01-04 06:18:10   6062   99200.000000   6062  5.200000
2014-01-04 06:23:03   6062   92805.801105   6062  5.200000
2014-01-04 06:24:12   6062   91300.000000   6062  5.257182
2014-01-04 06:29:05   6062   85472.375691   6062  5.500000
2014-01-04 06:30:14   6062   84100.000000   6062  5.500000
2014-01-04 06:35:08   6062   62151.239669   6062  5.500000
2014-01-04 06:36:17   6062   57000.000000   6062  5.500000

我认为通常最好在此停止,因为您保留了所有 csv 文件中的所有数据。但是你说你只想要最长的时间点csv。为此,您需要找到最长的DataFrame,然后获取与其索引对应的行。找到最长的DataFrame 很容易,您只需找到最大长度的DataFrame。只保留index 中的时间点也很容易,您只需使用index 进行切片(您使用loc 方法进行切片)。

longind = max(dataList.values(), key=len).index
df = df.loc[longind]

这将为您提供以下最终DataFrame

                         a                     b      
                    Volume          Value Volume Value
Date                                                  
2014-01-04 05:52:50    NaN            NaN   6062   4.7
2014-01-04 05:58:53    NaN            NaN   6062   4.7
2014-01-04 06:04:56   6062  107352.066116   6062   4.9
2014-01-04 06:10:58   6062   99267.955801   6062   5.1
2014-01-04 06:17:01   6062   98857.851240   6062   5.2
2014-01-04 06:23:03   6062   92805.801105   6062   5.2
2014-01-04 06:29:05   6062   85472.375691   6062   5.5
2014-01-04 06:35:08   6062   62151.239669   6062   5.5

如果你愿意,这可以合并成一行:

df = pd.concat(dataList.values(), axis=1, keys=dataList.keys()).interpolate('time').loc[max(dataList.values(), key=len).index]

或者,也许更清晰的 4 行:

names = dataList.keys()
dfs = dataList.values()
longind = max(dfs, key=len).index
df = pd.concat(dfs, axis=1, keys=names).interpolate('time').loc[longind]

我不确定为什么我的最终结果与您显示的不同。我自己在MATLAB (R2015A) 中运行了您的示例,得到的结果与我在这里得到的结果相同,因此我怀疑您使用与示例不同的数据集生成了最终数据。

【讨论】:

  • 如果我尝试您的解决方案会出现此错误:ValueError: time-weighted interpolation only works on Series or DataFrames with a DatetimeIndex
  • 是的,正如我所说,“我假设我们有两个 DataFrame,其中 DateDateTimeIndex。”您显然没有使用DateTimeIndex。确保您在致电read_csv 时有parse_dates=Trueindex_col='Date'
  • 好吧,我错过了prase_dates=True。但是使用您的代码,我只为两个数据框执行此操作。我有一个包含多个数据框的字典,需要对最长的数据框进行重新采样。我该如何管理?
  • 是的,它有效。我必须对其进行调整以实现我想要的格式,但重采样问题已解决。 TNX
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 2018-11-16
  • 2020-07-23
  • 2017-01-27
  • 2022-01-04
  • 2018-07-05
  • 1970-01-01
相关资源
最近更新 更多