使用 python 重新采样和合并数据框
Resampling and merging data frame with python
您好,我已经用这段代码创建了一个 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
您可以 concat
两个 DataFrames
、interpolate
,然后 reindex
在您想要的 DataFrame
上。
我假设我们有一定数量的 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
。我使用 dict
keys
作为 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
很容易,您只需找到长度最大的那一个即可。只保留那个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) 中的例子我自己得到了和我在这里得到的相同的结果,所以我怀疑你生成的最终数据与例子中的数据集不同。
您好,我已经用这段代码创建了一个 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
您可以 concat
两个 DataFrames
、interpolate
,然后 reindex
在您想要的 DataFrame
上。
我假设我们有一定数量的 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
。我使用 dict
keys
作为 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
很容易,您只需找到长度最大的那一个即可。只保留那个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) 中的例子我自己得到了和我在这里得到的相同的结果,所以我怀疑你生成的最终数据与例子中的数据集不同。