有没有一种pythonic方法可以将日期时间上的数据帧与具有不规则日期时间戳的数据对合并

Posted

技术标签:

【中文标题】有没有一种pythonic方法可以将日期时间上的数据帧与具有不规则日期时间戳的数据对合并【英文标题】:Is there a pythonic way to merge a dataframe on the datetime with datapairs with an irregular datetimestamp 【发布时间】:2019-12-02 13:40:46 【问题描述】:

我有几个数据系列,其中每个数据点都保存有时间戳,精度为 [ms]。我想将这些系列合并到一个时间线上,所有时间戳的采样精度应为 [s] 最后应该有一个 pd ,其中第一列是日期时间,具有来自系列的所有不同时间戳。所有其他列在该日期时间合并。

我的代码正在运行,但由于内存问题而无法处理大数据。

数据如下所示:

a_data; a_Timestamp; b_data; b_Timestamp; c_data ; c_Timestamp
1; 2019-07-24 12:00:00.123; 2 ; 2019-07-24 12:00:00.234; 3 ; 2019-07-24 12:00:00.345;
2; 2019-07-24 12:00:03.123; 3 ; 2019-07-24 12:00:02.234; 4 ; 2019-07-24 12:00:03.645;

我的代码如下:

import numpy as np
import pandas as pd
import datetime as dt

def prepareData(df):
    dfm = None
    df = df.dropna(axis='columns',how='all')
    df = df.sort_index()  

    for col in df:
        dt = None
        if not "Timestamp" in col:
            series = pd.DataFrame('DateTime' : pd.to_datetime(df[col + '_Timestamp']).astype('datetime64[s]'),col : df[col])
            if mergedFrame is not None:
                dfm = dfm.merge(series, on='DateTime', how ='outer').sort_values('DateTime')           
            else:
                dfm = series    
        dfm = dfm.loc[~dfm.DateTime.duplicated(keep='first')]
    dfm = dfm.sort_index()
    dfm = dfm.fillna(method='ffill')
    dfm = dfm.fillna(method='bfill')
    dfm = dfm.fillna(0)
    return dfm.reset_index()       

df = pd.read_csv('file.csv', sep = ";", na_values="n/a" ,low_memory=False)
prepareData(df).to_csv( 'file_sampled.csv', sep = ';')    

结果应该是

DateTime; a_data; b_data ; c_data
2019-07-24 12:00:00; 1;2;3
2019-07-24 12:00:02; 1;3;3
2019-07-24 12:00:03; 2;3;3 
2019-07-24 12:00:04; 2;3;4

我得到了这个结果,但它占用的内存对我的电脑来说太多了。我想有更好的方法来做到这一点。

【问题讨论】:

【参考方案1】:

首先我们选择每个数据和每个时间戳列并将它们并排放置:

x = pd.concat([pd.melt(df.iloc[:,::2], value_name='data'), pd.melt(df.iloc[:,1::2], value_name='DateTime').iloc[:,-1]], axis=1)

将日期时间字符串转换为DateTime,四舍五入为整秒并设置为索引:

x['DateTime'] = pd.to_datetime(x.DateTime).dt.round('s')
x = x.set_index('DateTime')

最后我们对数据进行透视:

x.pivot(columns='variable', values='data')

结果:

variable             a_data  b_data  c_data
DateTime                                   
2019-07-24 12:00:00     1.0     2.0     3.0
2019-07-24 12:00:02     NaN     3.0     NaN
2019-07-24 12:00:03     2.0     NaN     NaN
2019-07-24 12:00:04     NaN     NaN     4.0

【讨论】:

这看起来更像pythonic,我想它可以工作。但是我仍然遇到内存错误:(顺便说一句,我有 48GB 和 .csv 是 520 mb 也许我需要再多几步进行重新排序,例如每次只在 50 行上进行。这里的困难是并非每一列都记录在同一个周期中。对于某些数据,5 秒内有 5 个数据点,而另一些数据在 5 秒内只有 1 个。这导致每列的行长度不同。 如果你分块做呢?从 csv 读取整个数据帧后(df.info() 的最后一行)的内存使用量是多少? 606 列,dtypes:float64(343),object(264),内存使用:1.9+ GB。对于块,你的意思是像 for i in range(0, len(l), 50): yield l[i:i + n] 我运行你的代码似乎太快了。我上次尝试时没有清除内存,所以它之前已经被阻塞了。代码正在进行中,目前没有错误。 在我的第一行 x = pd.concat(... 之后插入 x['variable'] = x.variable.astype('category') 也将减少内存消耗(当然前提是您设法计算 x)

以上是关于有没有一种pythonic方法可以将日期时间上的数据帧与具有不规则日期时间戳的数据对合并的主要内容,如果未能解决你的问题,请参考以下文章

使用 pandas python 将字符串日期转换为列中所有值的数字

导入一年的每日日期

摆脱 Python 中日期字符串的前导零? [复制]

Shebang Notation:Windows 和 Linux 上的 Python 脚本?

删除/隐藏 UIDatePicker 最小/最大日期范围之外的行?

有没有一种好方法可以将 pychecker/pylint 应用于 Tornado 模板中的 python 代码?