Repository: movingpandas/movingpandas

Issue:
set_speed inaccurate with floating point (nanosecond) datetime values results in unmitigatable error

```python
# Your code here

```

#### Problem description
Trajectories that contain a datetime that has floating point  seconds value results in the dataframe of the trajectory getting one value withput cordinates added when calculating speed .

![grafik](https://github.com/user-attachments/assets/5bab01e5-3cfc-4f0a-946b-7ca9f8dbd940)

This results in 

![grafik](https://github.com/user-attachments/assets/82b082ee-c922-4cec-b1ea-120140584065)


This is due to the code in trajectory.py  line 1328 
```python 
 temp_df.at[self.get_start_time(), name] = temp_df.iloc[1][name]
```

As ``` self.get_start_time()``` reports the seconds value in integers: 
``` 
IPdb[16]: self.get_start_time()
Out  [16]: datetime.datetime(2024, 10, 25, 7, 39, 31, 250000)
```
However, in the assignment in line 1328 the 
```temp_df.at[self.get_start_time(), name]" ``` does not find the correct value in the index and thus defaults to adding another row to the dataframe (see screenshot up there) 

Visible when just calling the "startime" of the dataframe: 
```
temp_df.index[0]
Out  [19]: Timestamp('2024-10-25 07:39:31.250000477')
```

It seems that 
```return self.df.index.min().to_pydatetime()``` is swallowing the last values due to python datetime only supporting microseconds. 


#### Output of ``movingpandas.show_versions()``

<details>
MovingPandas 0.18.1

SYSTEM INFO
-----------
python     : 3.10.14 | packaged by Anaconda, Inc. | (main, May  6 2024, 19:44:50) [MSC v.1916 64 bit (AMD64)]
executable : C:\Users\Riedel\.conda\envs\tracjectory\python.exe
machine    : Windows-10-10.0.19045-SP0

GEOS, GDAL, PROJ INFO
---------------------
GEOS       : None
GEOS lib   : None
GDAL       : 3.6.2
GDAL data dir: None
PROJ       : 9.3.1
PROJ data dir: C:\Users\Riedel\.conda\envs\tracjectory\Library\share\proj

PYTHON DEPENDENCIES
-------------------
geopandas  : 0.14.2
pandas     : 2.2.2
fiona      : 1.9.5
numpy      : 1.26.4
shapely    : 2.0.1
rtree      : 1.0.1
pyproj     : 3.6.1
matplotlib : 3.7.1
mapclassify: 2.5.0
geopy      : 2.4.1
holoviews  : 1.19.1
hvplot     : 0.10.0
geoviews   : 1.12.0
stonesoup  : None

</details>


Discussion:

Patch:
diff --git a/movingpandas/trajectory.py b/movingpandas/trajectory.py
index 9b23cbf..48d01e4 100644
--- a/movingpandas/trajectory.py
+++ b/movingpandas/trajectory.py
@@ -1369,7 +1369,8 @@ class Trajectory:
         except ValueError as e:
             raise e
         # set the distance in the first row to zero
-        temp_df.at[self.get_start_time(), name] = 0
+        t0 = self.df.index.min().to_datetime64()
+        temp_df.at[t0, name] = 0
         temp_df = temp_df.drop(columns=["prev_pt"])
         return temp_df
 
@@ -1383,7 +1384,8 @@ class Trajectory:
         except ValueError as e:
             raise e
         # set the speed in the first row to the speed of the second row
-        temp_df.at[self.get_start_time(), name] = temp_df.iloc[1][name]
+        t0 = self.df.index.min().to_datetime64()
+        temp_df.at[t0, name] = temp_df.iloc[1][name]
         temp_df = temp_df.drop(columns=["prev_pt", "delta_t"])
         return temp_df
 
@@ -1396,7 +1398,8 @@ class Trajectory:
         )
         # set the acceleration in the first row to the acceleration of the
         # second row
-        temp_df.at[self.get_start_time(), name] = temp_df.iloc[1][name]
+        t0 = self.df.index.min().to_datetime64()
+        temp_df.at[t0, name] = temp_df.iloc[1][name]
         return temp_df.drop(columns=["speed_temp"])
 
     def intersects(self, polygon):


Test patch:
diff --git a/movingpandas/tests/test_trajectory.py b/movingpandas/tests/test_trajectory.py
index b19c91c..c818ee1 100644
--- a/movingpandas/tests/test_trajectory.py
+++ b/movingpandas/tests/test_trajectory.py
@@ -477,6 +477,19 @@ class TestTrajectory:
         traj.add_speed()
         traj.add_speed(overwrite=True)
 
+    def test_add_speed_with_nanoseconds(self):
+        import numpy as np
+
+        start_time = pd.Timestamp.now() + pd.Timedelta(nanoseconds=10)
+        timedeltas = np.arange(10) * pd.Timedelta(seconds=0.2)
+        timestamps = start_time + timedeltas
+        df = pd.DataFrame({"datetime": timestamps})
+        df["x"] = np.arange(0, 10) * 100
+        df["y"] = np.arange(0, 10) * 100
+        traj = Trajectory(df, traj_id=1, t="datetime", y="y", x="x", crs="epsg:32632")
+        traj.add_speed()
+        assert len(traj.df) == 10
+
     def test_add_acceleration(self):
         traj = make_traj([Node(0, 0), Node(6, 0, second=1), Node(18, 0, second=2)])
         traj.add_acceleration()