rwe*_*ter 1 python csv numpy pandas
我有一个大型时间序列数据框,其中包含单独列中的数字和布尔数据。我正在尝试将数据从 1 分钟间隔缩减为 15 分钟间隔。布尔列是系统状态,我正在努力研究如何对它们进行下采样并仍然保留任何故障。目前,我的重新采样使用last将忽略任何行上发生的任何系统故障,但最后一行。
我希望它做什么:如果在 15 分钟系列中的任何行上发生“故障”,那么重采样后的时间戳将显示为“故障”,否则将显示为“正常”。
我知道解决方案存在于how=''resample 中,但是因为我是 numpy 和 pandas 的新手,所以我不知道要使用什么。
我的代码:
import pandas as pd
# Reads .csv, combines Date and Time columns into Timestamp, sets Timestamp as index
df = pd.read_csv('data.csv', parse_dates = {'Timestamp' : ['Date', 'Time']}, index_col = 'Timestamp')
# Fixing any incomplete data and interpolating any numerical gaps
index = pd.date_range(freq='1min', start=df.first_valid_index(), end=df.last_valid_index())
df_clean = df.reindex(set(df.index).union(index))
for col in df_clean:
df_clean[col] = df_clean[col].interpolate('time').ix[index]
# Downsampling numerical data
df_avg = df_clean.resample('15min', how='mean')
# Downsampling boolean data separately
df_avg['alarm1']=df_clean['alarm1'].resample('15min', how='last')
# Fix for missing index name
df_avg.index.name = 'Timestamp'
# Adding date and time columns back to dataframe
df_avg.reset_index(level=0, inplace=True)
df_avg['Date'] = df_avg['Timestamp'].apply(lambda x: x.strftime('%Y/%m/%d'))
df_avg['Time'] = df_avg['Timestamp'].apply(lambda x: x.strftime('%H:%M:%S'))
# Write new .csv
df_avg[['Date','Time','A','B','C','alarm1']].to_csv('out.csv', index=False)
Run Code Online (Sandbox Code Playgroud)
docstring 说how应该是一个字符串,但实际上它也可以是一个可调用的。
如果 'alarm1' 列是布尔值,则可以使用how=any(或how=np.any)。 any将逻辑上or每个时间 bin 中的值,因此如果 bin 中的任何值为 True,则下采样系列中的值将为 True。
这是一个例子。
首先,设置随机种子并创建一系列布尔值。
In [101]: np.random.seed(123456)
In [102]: rng = pd.date_range('1/1/2011', periods=25, freq='1min')
In [103]: ts = pd.Series(np.random.rand(len(rng)) > 0.85, index=rng)
In [104]: ts
Out[104]:
2011-01-01 00:00:00 False
2011-01-01 00:01:00 True
2011-01-01 00:02:00 False
2011-01-01 00:03:00 True
2011-01-01 00:04:00 False
2011-01-01 00:05:00 False
2011-01-01 00:06:00 False
2011-01-01 00:07:00 False
2011-01-01 00:08:00 False
2011-01-01 00:09:00 False
2011-01-01 00:10:00 False
2011-01-01 00:11:00 False
2011-01-01 00:12:00 False
2011-01-01 00:13:00 True
2011-01-01 00:14:00 False
2011-01-01 00:15:00 False
2011-01-01 00:16:00 False
2011-01-01 00:17:00 False
2011-01-01 00:18:00 False
2011-01-01 00:19:00 False
2011-01-01 00:20:00 True
2011-01-01 00:21:00 False
2011-01-01 00:22:00 False
2011-01-01 00:23:00 False
2011-01-01 00:24:00 False
Freq: T, dtype: bool
Run Code Online (Sandbox Code Playgroud)
使用resample转换到5分钟一班。使用how=np.any逻辑上or的时间仓的值。
In [105]: ds = ts.resample('5min', how=np.any)
In [106]: ds
Out[106]:
2011-01-01 00:00:00 True
2011-01-01 00:05:00 False
2011-01-01 00:10:00 True
2011-01-01 00:15:00 False
2011-01-01 00:20:00 True
Freq: 5T, dtype: bool
Run Code Online (Sandbox Code Playgroud)
您还可以对这些值求和,这将为您提供每个时间段中的警报数量:
In [107]: ts.resample('5min', how=sum)
Out[107]:
2011-01-01 00:00:00 2
2011-01-01 00:05:00 0
2011-01-01 00:10:00 1
2011-01-01 00:15:00 0
2011-01-01 00:20:00 1
Freq: 5T, dtype: float64
Run Code Online (Sandbox Code Playgroud)
更新:
如果如评论中所述,该alarm1列包含字符串'YES'和'NO',则有多种方法可以处理它。例如,您可以简单地将值转换为布尔值(例如tsbool = ts == 'YES')并使用上述技术。
或者,您可以编写自定义聚合函数,例如
def func(faults):
return 'YES' if np.any(faults == 'YES') else 'NO'
Run Code Online (Sandbox Code Playgroud)
并将其作为 的how参数resample。这是一个例子。
首先,创建一个包含字符串“YES”和“NO”的系列。
In [60]: rng = pd.date_range('1/1/2011', periods=25, freq='1min')
In [61]: yn = np.array(['NO', 'YES'])
In [62]: ts = pd.Series(yn[(np.random.rand(len(rng)) > 0.85).astype(int)], index=rng)
In [63]: ts
Out[63]:
2011-01-01 00:00:00 NO
2011-01-01 00:01:00 NO
2011-01-01 00:02:00 NO
2011-01-01 00:03:00 NO
2011-01-01 00:04:00 YES
2011-01-01 00:05:00 YES
2011-01-01 00:06:00 NO
2011-01-01 00:07:00 YES
2011-01-01 00:08:00 NO
2011-01-01 00:09:00 NO
2011-01-01 00:10:00 NO
2011-01-01 00:11:00 NO
2011-01-01 00:12:00 NO
2011-01-01 00:13:00 NO
2011-01-01 00:14:00 NO
2011-01-01 00:15:00 NO
2011-01-01 00:16:00 YES
2011-01-01 00:17:00 NO
2011-01-01 00:18:00 NO
2011-01-01 00:19:00 NO
2011-01-01 00:20:00 NO
2011-01-01 00:21:00 NO
2011-01-01 00:22:00 NO
2011-01-01 00:23:00 NO
2011-01-01 00:24:00 NO
Freq: T, dtype: object
Run Code Online (Sandbox Code Playgroud)
定义将“YES”和“NO”字符串数组缩减为单个字符串的函数。
In [64]: def func(alarms):
....: return 'YES' if np.any(alarms == 'YES') else 'NO'
....:
Run Code Online (Sandbox Code Playgroud)
使用该函数重新采样ts。
In [65]: ds = ts.resample('5min', how=func)
In [66]: ds
Out[66]:
2011-01-01 00:00:00 YES
2011-01-01 00:05:00 YES
2011-01-01 00:10:00 NO
2011-01-01 00:15:00 YES
2011-01-01 00:20:00 NO
Freq: 5T, dtype: object
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1746 次 |
| 最近记录: |