提问人:Karma_X 提问时间:8/23/2023 最后编辑:Karma_X 更新时间:8/23/2023 访问量:66
从数据帧中切片和提取
Slicing and extracting from dataframe
问:
我有一个如下的数据帧:
time power speed state
1 14.00 29 3 1
2 14.01 30 3 2
3 14.02 29 3 3
4 14.03 30 3 4
5 14.04 29 3 5
6 14.05 30 3 6
7 14.06 29 3 6
8 14.07 30 3 6
9 14.08 29 3 6
10 14.09 30 3 5
11 14.10 29 3 5
12 14.11 30 3 5
13 14.12 29 3 5
14 14.13 30 3 6
15 14.14 31 4 6
16 14.15 32 4 6
每个循环从状态 5(第 10 行,仅在状态 6 之后)开始,并在状态 6 返回之前结束(即第 13 行)。因此,循环 1 在第 10 行和第 13 行之间。
这是一个大数据,有多个周期。我想将每个周期提取为数据帧。 我尝试了一些迭代,但没有奏效。
charge_cycles = []
current_charge_start = None
current_drive_start = None
total_energy_consumed = 0
drive_data = []
for index, row in data.iterrows():
if row['state'] == '6':
if current_drive_start is not None:
energy_during_drive = total_energy_consumed
charge_cycles.append(energy_during_drive)
drive_data.append(data.loc[current_drive_start:index])
current_drive_start = None
total_energy_consumed = 0
current_charge_start = row['time']
elif row['state'] == '5':
if current_charge_start is not None and current_drive_start is None:
current_drive_start = index
if current_drive_start is not None:
total_energy_consumed += row['power'] * (row['time'] - data.loc[current_drive_start, 'time'])
current_drive_start = index
# Print the energy consumption during driving between each charge cycle
for i, energy in enumerate(charge_cycles, start=1):
print(f"Charge Cycle {i}: Energy Consumed During Driving = {energy} units")
# Display the DataFrames for each driving cycle
for i, drive_df in enumerate(drive_data, start=1):
print(f"Driving Cycle {i}:\n{drive_df}")
结果,这给了我整个数据框。任何人都可以帮我解决这个问题的python代码吗?
答:
2赞
mozway
8/23/2023
#1
您可以尝试使用布尔索引和 .groupby
如果只想在状态 6 之后启动的组,请添加一些筛选。
m1 = df['state'].eq(5)
m2 = df['state'].eq(6)
m3 = m2.mask(m1).ffill()
dfs = [g for k,g in df[m1&m3].groupby(m2.cumsum())]
或两个状态之间 6:
m1 = df['state'].eq(5)
m2 = df['state'].eq(6)
m3 = m2.mask(m1).ffill() & m2.mask(m1).bfill()
dfs = [g for k,g in df[m1&m3].groupby(m2.cumsum())]
数据帧的输出列表:
[ time power speed state
10 14.09 30 3 5
11 14.10 29 3 5
12 14.11 30 3 5
13 14.12 29 3 5]
使用注释中的示例输出,并且仅考虑组前的 6:
[ state
6 5
7 5
8 5
9 5
10 5
11 5
12 5
13 5
14 5
15 5
16 5
17 5
18 5
19 5,
state
50 5
51 5
52 5
53 5
54 5
55 5
56 5
57 5]
如果你想要所有的数字:
m1 = df['state'].eq(5)
m2 = df['state'].eq(6)
m3 = m1.where(m1|m2).ffill()
dfs = [g for k,g in df[m3&~m2].groupby(m2.cumsum())]
输出:
[ state
6 5
7 5
8 5
9 5
10 5
11 5
12 5
13 5
14 5
15 5
16 5
17 5
18 5
19 5
20 4
21 3
22 5
23 5
24 5
25 5
26 5
27 5
28 5
29 1
30 2
31 5
32 5
33 5,
state
50 5
51 5
52 5
53 5
54 5
55 5
56 5
57 5
58 4
59 1
60 2
61 3
62 4
63 4]
评论
0赞
RomanPerekhrest
8/23/2023
带有行索引的记录不应该存在(它不在周期内)5
0赞
mozway
8/23/2023
@RomanPerekhrest不清楚,OP 只是说有两个周期,但我会用另一种方法更新
0赞
Karma_X
8/23/2023
@mozway 感谢您的回复。正如 Roman 所说,行索引 5 不应该在那里
0赞
RomanPerekhrest
8/23/2023
@mozway,OP说,关于他的评论:这是关于6666665555555555555543555555512555666666666666666655555555412344666666666
0赞
mozway
8/23/2023
@Karma_X好的,那就使用第二种方法
2赞
Andrej Kesely
8/23/2023
#2
IIUC,您可以尝试:
df = pd.DataFrame(
{
"state": list(
"6666665555555555555543555555512555666666666666666655555555412344666666666"
)
}
)
df["state"] = df["state"].astype(int)
# remove the initial values 'till 6
df = df.loc[df["state"].eq(6).idxmax() :]
mask = df["state"].eq(6)
for _, g in df.groupby((mask != mask.shift()).cumsum()):
if (eq5 := g["state"].eq(5)).any():
g = g.loc[eq5.idxmax() :]
print(g)
print("-" * 80)
指纹:
state
6 5
7 5
8 5
9 5
10 5
11 5
12 5
13 5
14 5
15 5
16 5
17 5
18 5
19 5
20 4
21 3
22 5
23 5
24 5
25 5
26 5
27 5
28 5
29 1
30 2
31 5
32 5
33 5
--------------------------------------------------------------------------------
state
50 5
51 5
52 5
53 5
54 5
55 5
56 5
57 5
58 4
59 1
60 2
61 3
62 4
63 4
--------------------------------------------------------------------------------
评论
1赞
Karma_X
8/23/2023
嘿@Andrej Kesely,非常感谢你的回答。这对我来说非常有效。
评论