从满足数据框 Python 条件的列表中索引并保存最后 N 个点
Posted
技术标签:
【中文标题】从满足数据框 Python 条件的列表中索引并保存最后 N 个点【英文标题】:Index and save last N points from a list that meets conditions from dataframe Python 【发布时间】:2021-06-05 20:47:17 【问题描述】:我有一个包含气体浓度和相应阀门编号的 DataFrame。这些数据是连续采集的,我们来回切换阀门(阀门 = 1 或 2)一段时间,以获得每个阀门值的 10 个循环(总共 20 个循环)。数据的 sn-p 看起来像这样(我有 2,000 多个点,每个阀门每个循环保持大约 90 秒):
gas1 valveW time
246.9438 2 1
247.5367 2 2
246.7167 2 3
246.6770 2 4
245.9197 1 5
245.9518 1 6
246.9207 1 7
246.1517 1 8
246.9015 1 9
246.3712 2 10
247.0826 2 11
... ... ...
我的目标是保存每个阀门循环的最后 N 个点。例如,在阀门=1 的第一个循环中,我想在阀门切换到 2 之前索引并保存最后 N 个点。然后我会保存最后 N 个点并对它们进行平均以找到一个值来表示第一个循环。然后我想再次在valve=1时重复此步骤进行第二个循环。
我目前正在从 Matlab 转换为 Python,所以这是我要翻译的 Matlab 代码:
% NOAA high
n2o_noaaHigh = [];
co2_noaaHigh = [];
co_noaaHigh = [];
h2o_noaaHigh = [];
ind_noaaHigh_end = zeros(1,length(t_c));
numPoints = 40;
for i = 1:length(valveW_c)-1
if (valveW_c(i) == 1 && valveW_c(i+1) ~= 1)
test = (i-numPoints):i;
ind_noaaHigh_end(test) = 1;
n2o_noaaHigh = [n2o_noaaHigh mean(n2o_c(test))];
co2_noaaHigh = [co2_noaaHigh mean(co2_c(test))];
co_noaaHigh = [co_noaaHigh mean(co_c(test))];
h2o_noaaHigh = [h2o_noaaHigh mean(h2o_c(test))];
end
end
ind_noaaHigh_end = logical(ind_noaaHigh_end);
这是我目前对 Python 的了解:
# NOAA high
n2o_noaaHigh = [];
co2_noaaHigh = [];
co_noaaHigh = [];
h2o_noaaHigh = [];
t_c_High = []; # time
for i in range(len(valveW_c)):
# NOAA HIGH
if (valveW_c[i] == 1):
t_c_High.append(t_c[i])
n2o_noaaHigh.append(n2o_c[i])
co2_noaaHigh.append(co2_c[i])
co_noaaHigh.append(co_c[i])
h2o_noaaHigh.append(h2o_c[i])
提前致谢!
【问题讨论】:
【参考方案1】:如果您的数据框按时间排序,您可以像这样获得每个阀门的最后 N 条记录。
N=2
valve1 = df[df['valveW']==1].iloc[-N:,:]
valve2 = df[df['valveW']==2].iloc[-N:,:]
如果当前没有排序,您可以轻松地像这样对其进行排序。
df.sort_values(by=['time'])
【讨论】:
【参考方案2】:我不确定我是否理解正确,但我想这就是你要找的:
# First we create a column to show cycles:
df['cycle'] = (df.valveW.diff() != 0).cumsum()
print(df)
gas1 valveW time cycle
0 246.9438 2 1 1
1 247.5367 2 2 1
2 246.7167 2 3 1
3 246.677 2 4 1
4 245.9197 1 5 2
5 245.9518 1 6 2
6 246.9207 1 7 2
7 246.1517 1 8 2
8 246.9015 1 9 2
9 246.3712 2 10 3
10 247.0826 2 11 3
现在您可以使用groupby
方法获取每个周期最后n 个点的平均值:
n = 3 #we assume this is n
df.groupby('cycle').apply(lambda x: x.iloc[-n:, 0].mean())
输出:
cycle 0
1 246.9768
2 246.6579
3 246.7269
【讨论】:
我认为您可能想使用.iloc
而不是loc
。我相信当前代码返回所有行的平均值(相当于df.groupby('cycle').mean()
)【参考方案3】:
让我们调用你的 DataFrame df
;那么你可以这样做:
results =
for k, v in df.groupby((df['valveW'].shift() != df['valveW']).cumsum()):
results[k] = v
print(f'[group k]')
print(v)
Shift()
,正如它所暗示的,移动阀门循环的列允许检测数字序列的变化。然后,cumsum()
有助于为具有相同编号顺序的每个组分配一个唯一编号。然后我们可以在这个专栏上做一个groupby()
(这在以前是不可能的,因为组不是一个就是两个!)。
给出例如为您的代码 sn-p(保存在results
):
[group 1]
gas1 valveW time
0 246.9438 2 1
1 247.5367 2 2
2 246.7167 2 3
3 246.6770 2 4
[group 2]
gas1 valveW time
4 245.9197 1 5
5 245.9518 1 6
6 246.9207 1 7
7 246.1517 1 8
8 246.9015 1 9
[group 3]
gas1 valveW time
9 246.3712 2 10
10 247.0826 2 11
然后得到每个循环的平均值;你可以例如做:
df.groupby((df['valveW'].shift() != df['valveW']).cumsum()).mean()
它给出(再次为您的代码 sn-p):
gas1 valveW time
valveW
1 246.96855 2.0 2.5
2 246.36908 1.0 7.0
3 246.72690 2.0 10.5
你不会太在意时间的意思,但 gas1 !
然后,基于results
你可以例如做:
n = 3
mean_n_last = []
for k, v in results.items():
if len(v) < n:
mean_n_last.append(np.nan)
else:
mean_n_last.append(np.nanmean(v.iloc[len(v) - n:, 0]))
它为n = 3
提供[246.9768, 246.65796666666665, nan]
!
【讨论】:
这很有帮助!如何平均每个循环的最后 N 个元素?您的答案是整个周期的平均值。【参考方案4】:我们可以使用中间的block
列来标识所有块。然后我们groupby
块并对最后的nth
元素进行操作。
使用您的示例数据,我们为每个1
或2
部分创建block
列:
df['block'] = (df.valveW != df.valveW.shift()).cumsum()
gas1 | valveW | time | block | |
---|---|---|---|---|
0 | 246.9438 | 2 | 1 | 1 |
1 | 247.5367 | 2 | 2 | 1 |
2 | 246.7167 | 2 | 3 | 1 |
3 | 246.6770 | 2 | 4 | 1 |
4 | 245.9197 | 1 | 5 | 2 |
5 | 245.9518 | 1 | 6 | 2 |
6 | 246.9207 | 1 | 7 | 2 |
7 | 246.1517 | 1 | 8 | 2 |
8 | 246.9015 | 1 | 9 | 2 |
9 | 246.3712 | 2 | 10 | 3 |
10 | 247.0826 | 2 | 11 | 3 |
然后我们groupby
那些块并取最后一个n
的平均值:
n = 2
df.groupby('block').nth(list(range(-n, 0))).gas1.mean(axis=0, level=0)
结果是每个区块最后一个n
的平均值:
block
1 246.69685
2 246.52660
3 246.72690
Name: gas1, dtype: float64
【讨论】:
以上是关于从满足数据框 Python 条件的列表中索引并保存最后 N 个点的主要内容,如果未能解决你的问题,请参考以下文章