我有一个很大的数据集,我从CSV读取到了具有1s频率日期时间索引的数据帧。加载时,df约为2.5gb。大多数数据存储为np.float32。在获取源数据的过程中,有时会在16hz处对其进行采样,但是CSV被索引为1秒的行,因此突发数组数据以CH [0],CH [1] ... CH [15]的形式存储沿着第二排。因此,CH0表示时间为零,CH1表示时间+ 0.0625s,以此类推。我想对此数据进行清理,以便每秒钟的测量都有一个新行。因此,基本上是同一列中16列而不是1列16列中来自该度量的所有数据。数据集中有数百个这样的突发通道,但是突发期间的数据简化版本(为简单起见更改为4hz)如下所示。突发采集结束后,数据返回到NaN:

我不知道从哪里开始:(

                      CH0  CH1  CH2  CH3
TIME
2019-02-09 12:53:06   29   12   43   10
2019-02-09 12:53:07   56   15   77   88
2019-02-09 12:53:08   82    9   95   19
2019-02-09 12:53:09   13   13   79    1
2019-02-09 12:53:10   35   87   77   37
2019-02-09 12:53:11   53    9    5    9
2019-02-09 12:53:12   25   63   78   70
2019-02-09 12:53:13   23   62   41   22
2019-02-09 12:53:14   21   52   10   82


我希望数据看起来像这样(显示前2秒):

                        CH0  CH1  CH2  CH3
TIME
2019-02-09 12:53:06.00   29   Nan  Nan  Nan
2019-02-09 12:53:06.25   12   Nan  Nan  Nan
2019-02-09 12:53:06.50   43   Nan  Nan  Nan
2019-02-09 12:53:06.75   10   Nan  Nan  Nan
2019-02-09 12:53:07.00   56   Nan  Nan  Nan
2019-02-09 12:53:07.25   15   Nan  Nan  Nan
2019-02-09 12:53:07.50   77   Nan  Nan  Nan
2019-02-09 12:53:07.75   88   Nan  Nan  Nan
2019-02-09 12:53:08.00   82   Nan  Nan  Nan


数据复制到新列(例如df ['CH'])还是重用CH0都没有关系。然后,我将删除CH1等列。

编辑:

我尝试了提供的答案,但是当“ TIME”已定义为索引时遇到了障碍。我在第20行df1 ['TIME'] = df ['TIME']遇到关键错误,我得到这个假设我认为TIME不再作为一列存在,所以我尝试:

df1.index = df.index

那没用。有人可以根据日期时间已经存在的索引建议对代码进行更改。我当前的完整代码(包括我如何生成概念证明数据)如下所示:

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

#Set up df to be representative of the real data, time indexed to 1s.
date_today = dt.datetime.now()
time = pd.date_range(date_today, date_today + dt.timedelta(0.0001), freq='s')

np.random.seed(seed=9)
data0 = np.random.randint(1, high=100, size=len(time))
data1 = np.random.randint(1, high=100, size=len(time))
data2 = np.random.randint(1, high=100, size=len(time))
data3 = np.random.randint(1, high=100, size=len(time))
df = pd.DataFrame({'TIME': time, 'CH0': data0, 'CH1':data1, 'CH2':data2, 'CH3':data3 })
df = df.set_index('TIME')
df.index = df.index.round('s')
print(df)

df1 = pd.DataFrame()
df1['TIME'] = (df['TIME'])
df1['CH'] = df['CH0']

df2 = pd.DataFrame()
df2['TIME'] = (df['TIME'] + dt.timedelta(milliseconds=250))
df2['CH'] = df['CH1']

df3 = pd.DataFrame()
df3['TIME'] = (df['TIME'] + dt.timedelta(milliseconds=500))
df3['CH'] = df['CH2']

df4 = pd.DataFrame()
df4['TIME'] = (df['TIME'] + dt.timedelta(milliseconds=750))
df4['CH'] = df['CH3']

result = pd.concat([df1, df2, df3, df4], ignore_index=True)
#result.sort_values(by=['TIME'])

print(result)

最佳答案

您可以添加毫秒并连接数据:

df1 = pd.DataFrame()
df1['time'] = pd.to_datetime(df['time'])
df1['CH0'] = df['CH0']

df2 = pd.DataFrame()
df2['time'] = pd.to_datetime(df['time'] + datetime.timedelta(milliseconds=250))
df2['CH0'] = df['CH1']

df3 = pd.DataFrame()
df3['time'] = pd.to_datetime(df['time'] + datetime.timedelta(milliseconds=500))
df3['CH0'] = df['CH2']

df4 = pd.DataFrame()
df4['time'] = pd.to_datetime(df['time'] + datetime.timedelta(milliseconds=750))
df4['CH0'] = df['CH3']

result = pd.concat([df1, df2, df3, df4])
result.sort('time')


如果您的列已经是日期时间,则可以省略pd.to_datetime。
请记住import datetime
在concat中,您可以使用ignore_index=True
但我认为第一次设定时间索引会更快。
如果您想让它更干,可能可以使用该代码循环甚至制作lambda。

关于python - 使用另一列中的数据对行进行子集,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54609848/

10-09 22:41
查看更多