Posts: 2
Threads: 1
Joined: Sep 2024
Sep-13-2024, 11:12 PM
(This post was last modified: Sep-13-2024, 11:13 PM by nmancini.)
Hi everyone,
I have dataframe including a list of intensity values (int) across time frames (frame). The list starts with negative time frame values, then reach 0 (which corresponds to an event, such as neuron stimulation), and continues with positive time frame values. This constitutes one cycle, with negative values are time points before stimulation, and positive values are time points after stimulation.
I have 4 cycles in total and want to assign a certain number (e.g. 1, 2, 3, 4). Those are my criteria for cycle assignment:
Cycle Start: Look for the first negative value in the segment before the next stimulation frame
Cycle End: Look for the last positive value in the segment following the current stimulation frame.
For some reasons, I am struggling to implement that into my script. I even tried using copilot, but still failed, so I wanted to know whether one of you would have any insight?
Thanks a lot!
Posts: 6,783
Threads: 20
Joined: Feb 2020
Sep-14-2024, 01:53 PM
(This post was last modified: Sep-14-2024, 01:53 PM by deanhystad.)
Can you provide sample input and desired output?
Are time sequence numbers always consecutive in a segment? If so, you could use the shift command to find numbers out of sequence.
import pandas as pd
# Make some data
df = pd.DataFrame({"time":[-2, -1, 0, 1, -1, 0, 1, 0, 1, 2, 3]})
# Make new series that is the time series data down 1 row + 1. As long as numbers in time
# are sequential, time == shifted time. Set first value in shifted time to something that won't
# match anything in time.
df["shifted"] = (df.time.shift(1, fill_value=0.5) + 1)
# Find where time != shifted time. This is the start of a series.
df["mismatch"] = df.time != df.shifted
# Count the mismatches. This is the series number.
df["series"] = df.mismatch.cumsum()
print(df) Output: time shifted mismatch series
0 -2 1.5 True 1
1 -1 -1.0 False 1
2 0 0.0 False 1
3 1 1.0 False 1
4 -1 2.0 True 2
5 0 0.0 False 2
6 1 1.0 False 2
7 0 2.0 True 3
8 1 1.0 False 3
9 2 2.0 False 3
10 3 3.0 False 3
Doing it all in one line.
import pandas as pd
df = pd.DataFrame({"time":[-2, -1, 0, 1, -1, 0, 1, 0, 1, 2, 3]})
df["series"] = (df.time != (df.time.shift(1, fill_value=0.5) + 1)).cumsum()
print(df) Output: time series
0 -2 1
1 -1 1
2 0 1
3 1 1
4 -1 2
5 0 2
6 1 2
7 0 3
8 1 3
9 2 3
10 3 3
Posts: 2
Threads: 1
Joined: Sep 2024
Hi, thanks for your reply!
Time sequence are NOT always consecutive in a segment.
Actually, I should have something like this (simplified here)
df = pd.DataFrame({"time": [-3, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, 3, 4, -2, -1, 0, 1, 2, 3], "deltaF_F": [-0.5, 1, 5, 6, 5, -7, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, 3]})
print(df)
Then I should have a script that creates another column called "cycle', in which I assign number of cycles. Given that I have three 0 in the time column, I should have 3 cycles.
In the column "time", the first negative values before the first 0 and all the positive values after this 0 should be attributed Cycle 1. Cycle 2 starts at the next first encountered negative value (-2), reaches the second 0, and ends at last positive value (4). Same for cycle 3.
Best,
Posts: 6,783
Threads: 20
Joined: Feb 2020
Sep-16-2024, 09:35 PM
(This post was last modified: Sep-16-2024, 09:36 PM by deanhystad.)
In your example the time values are sequential in each cycle. If we assume time values may not be sequential, can we assume they will always be increasing? If so, you can check if time[i] < time[i-1].
import pandas as pd
# Make some data
df = pd.DataFrame({"time": [-3, -1, 0, 1, -5, 0, 1, 0, 1, 2, 3]})
# Make new series that is the time series data shifted down 1 row. Replace the NULL value in row 0 with
# some number larger than df.time[0].
df["shifted"] = df.time.shift(1, fill_value=df.time.max() + 1)
# Find rows where df.time < df.shifted. These are the start of a cycle.
df["less_than"] = df.time < df.shifted
# Count the mismatches. This is the cycle number.
df["cycle"] = df.less_than.cumsum()
print(df)
# In one line.
df = pd.DataFrame({"time": [-3, -1, 0, 1, -5, 0, 1, 0, 1, 2, 3]})
df["cycle"] = (df.time < df.time.shift(1, fill_value=df.time.max() + 1)).cumsum()
print(df) Output: time shifted less_than cycle
0 -3 4 True 1
1 -1 -3 False 1
2 0 -1 False 1
3 1 0 False 1
4 -5 1 True 2
5 0 -5 False 2
6 1 0 False 2
7 0 1 True 3
8 1 0 False 3
9 2 1 False 3
10 3 2 False 3
time cycle
0 -3 1
1 -1 1
2 0 1
3 1 1
4 -5 2
5 0 2
6 1 2
7 0 3
8 1 3
9 2 3
10 3 3
|