1

I got this time array and I need to subtract the previous value from the next value. Like line 1-line 2 and line 3- line 4. I have been battling with this for days now, the problem now is how I will make the subtraction.

Here is the data:

2017-12-21T14:49:17.518Z
2017-12-21T14:50:49.723Z
2017-12-21T14:50:54.028Z
2017-12-21T14:50:54.343Z
2017-12-21T14:50:59.084Z
2017-12-21T14:50:59.399Z
2017-12-21T14:51:04.142Z
2017-12-21T14:51:04.457Z
2017-12-21T14:51:09.204Z
2017-12-21T14:51:09.521Z
2017-12-21T14:51:14.261Z
2017-12-21T14:51:14.579Z
2017-12-21T14:51:19.326Z
2017-12-21T14:51:19.635Z
2017-12-21T14:51:24.376Z
2017-12-21T14:51:24.691Z
2017-12-21T14:51:29.435Z
2017-12-21T14:51:29.750Z
2017-12-21T14:51:34.498Z
2017-12-21T14:51:34.813Z

I need to subtract the second from first, third from fourth, fifth from the sixth, and so on. Then get the result together in anther array and add them together.

pault
  • 41,343
  • 15
  • 107
  • 149
mufty__py
  • 127
  • 1
  • 12
  • 1
    What have you tried so far? Where are you getting stuck? Do you have any code that you can share? Are these strings or datetime objects? – pault Feb 09 '18 at 01:59
  • They are datetime object... It's a long question actually, this is just the last part. this is what i have tried so far [link](https://stackoverflow.com/questions/48654970/subtraction-of-time-in-two-different-lines-in-a-text-file-using-python) – mufty__py Feb 09 '18 at 02:02
  • If they are datetime objects then you can just subtract them. What's your desired output? – pault Feb 09 '18 at 02:04
  • maybe in seconds, but i want to subtract line 1 from line 2, line 3 from 4 and so on. Can you help please – mufty__py Feb 09 '18 at 02:09

2 Answers2

1

This is one way via dateutil.parser.parse:

from dateutil import parser

lst = ['2017-12-21T14:49:17.518Z',
       '2017-12-21T14:50:49.723Z',
       '2017-12-21T14:50:54.028Z',
       '2017-12-21T14:50:54.343Z',
       '2017-12-21T14:50:59.084Z',
       '2017-12-21T14:50:59.399Z']

lst = list(map(parser.parse, lst))
changes = [(j-i) for i, j in zip(lst, lst[1:])][::2]

To convert this to seconds:

seconds = [i.total_seconds() for i in changes]
jpp
  • 159,742
  • 34
  • 281
  • 339
  • oh, i really don't know about this panda module, does it work on python 2.7 and can i used an imported text file instead of list>? – mufty__py Feb 09 '18 at 02:18
  • @idrisbadmus, i have updated with `dateutil` solution. yes, you can read a imported text file to a list in python. – jpp Feb 09 '18 at 02:21
  • oh, i just checked now that panda wasn't in my win 2.7 version . Thanks though, yeah i can import text to list, just wanted to know if it was possible with panda. Thank again – mufty__py Feb 09 '18 at 02:33
  • `parser.parse` is much cleaner than `strptime(...)`. Is `dateutil` a standard package now? – pault Feb 09 '18 at 02:34
  • 1
    @pault, not yet but it should be, i'll add a link in my post. – jpp Feb 09 '18 at 02:35
  • @jp_data_analysis can you help with subtracting first from second , 3rd from fourth, and so on. Thats where i am actually stuck since, – mufty__py Feb 09 '18 at 02:47
  • but these are the changes between consecutive times, right? `changes = [(j-i) for i, j in zip(lst, lst[1:])]` – jpp Feb 09 '18 at 02:48
  • @jp_data_analysis You include third minus second. – Stefan Pochmann Feb 09 '18 at 03:22
  • @StefanPochmann, in that case you can ignore every second result from `changes`? i'll update accordingly. – jpp Feb 09 '18 at 09:30
0

Here is a way to do it with the datetime library and the strptime function:

From your previous question, it seems like your times are a list of strings.

times = [
    '2017-12-21T14:49:17.518Z',
    '2017-12-21T14:50:49.723Z',
    '2017-12-21T14:50:54.028Z',
    '2017-12-21T14:50:54.343Z',
    '2017-12-21T14:50:59.084Z',
    '2017-12-21T14:50:59.399Z',
    '2017-12-21T14:51:04.142Z',
    '2017-12-21T14:51:04.457Z',
    '2017-12-21T14:51:09.204Z',
    '2017-12-21T14:51:09.521Z',
    '2017-12-21T14:51:14.261Z',
    '2017-12-21T14:51:14.579Z',
    '2017-12-21T14:51:19.326Z',
    '2017-12-21T14:51:19.635Z',
    '2017-12-21T14:51:24.376Z',
    '2017-12-21T14:51:24.691Z',
    '2017-12-21T14:51:29.435Z',
    '2017-12-21T14:51:29.750Z',
    '2017-12-21T14:51:34.498Z',
    '2017-12-21T14:51:34.813Z'
]

Convert them to datetime objects using strptime.The map() function applies a function to each element in an iterable.

times_converted = map(
    lambda x: datetime.datetime.strptime(x, '%Y-%m-%dT%H:%M:%S.%fZ'), 
    times
)

The second argument to strptime above is the format string, which defines how the conversion should happen.

Now you can subtract consecutive times and use the total_seconds() method of datetime.timedelta to get the difference as desired:

diffs = [
    (b-a).total_seconds() for a, b in zip(times_converted[::2], times_converted[1::2])
]
#[92.205, 0.315, 0.315, 0.315, 0.317, 0.318, 0.309, 0.315, 0.315, 0.315]

I used zip() to get pairs of times from the list to subtract. The notation [::2] means take every other item in the list, starting at index 0. Likewise [1::2] means take every other item in the list, starting at index 1. More on python's slice notation here.

If you're not comfortable with list comprehensions and zip(), the above code can also be written as single for loop:

diffs = []
for i in range(0,len(times), 2):
    diffs.append((times_converted[i+1]-times_converted[i]).total_seconds())

More on zip()

The zip() function takes two iterables and returns pairs of tuples. For instance, consider the following example:

# suppose you had two lists
X = ['A', 'B', 'C']
Y = ['X', 'Y', 'Z']
print(zip(X, Y))
#[('A', 'X'), ('B', 'Y'), ('C', 'Z')]

So essentially it takes one item from the first list and one item from the second list and returns this as a tuple.

pault
  • 41,343
  • 15
  • 107
  • 149
  • in my last answer, i later extracted just the time out using spilt function. thanks alot. please can you recommend where i can understand datetime well. am self learning and i haven't found except the python site. – mufty__py Feb 09 '18 at 02:32
  • @idrisbadmus Here is the [link to the docs](https://docs.python.org/2/library/datetime.html#module-datetime) for `datetime`. There are a lot of good examples on that page. Good luck. – pault Feb 09 '18 at 02:36
  • @idrisbadmus Does this actually do what you want? You said you want second-first, fourth-third, etc, not also third-second. Also, it does look like they come in real pairs. Like you're doing some operation every five seconds and each time it takes about 0.3 seconds. – Stefan Pochmann Feb 09 '18 at 02:39
  • oh No, just checking well now. @pault, i need it to subtract second-first , fourth-third. I thought that's whats it did, but this subtract second-first, third secoud, fourth- third. – mufty__py Feb 09 '18 at 02:44
  • @idrisbadmus I updated the code as you specified. The only change was in the `zip()` part - we are getting different pairs slices to subtract. – pault Feb 09 '18 at 02:48
  • oh, you mean you still have the old answers right, and can you just help me past in the comment session, the former answer in the 'zip()'. i just want to learn the difference – mufty__py Feb 09 '18 at 02:52
  • I'll edit the post to add more explanation on the difference. – pault Feb 09 '18 at 02:54