J'essaie d'interpoler entre les points de temps pour toutes les données dans un dataframe pandas. Mes données actuelles sont par incréments de temps de 0,04 seconde. Je veux qu'il soit par incréments de 0,01 seconde pour correspondre à un autre ensemble de données. Je réalise que je peux utiliser la fonction DataFrame.interpolate () pour ce faire. Cependant, je ne sais pas comment insérer 3 lignes de NaN entre chaque ligne de mon dataframe de manière efficace.

import pandas as pd
import numpy as np

df = pd.DataFrame(data={"Time": [0.0, 0.04, 0.08, 0.12], 
                        "Pulse": [76, 74, 77, 80],
                        "O2":[99, 100, 99, 98]})
df_ins = pd.DataFrame(data={"Time": [np.nan, np.nan, np.nan], 
                            "Pulse": [np.nan, np.nan, np.nan],
                            "O2":[np.nan, np.nan, np.nan]})

Je veux que df se transforme à partir de ceci:

    Time    Pulse   O2
0   0.00    76      99
1   0.04    74      100
2   0.08    77      99
3   0.12    80      98

Pour quelque chose comme ça:

    Time    Pulse   O2
0   0.00    76      99
1   NaN     NaN     NaN
2   NaN     NaN     NaN
3   NaN     NaN     NaN
4   0.04    74      100
5   NaN     NaN     NaN
6   NaN     NaN     NaN
7   NaN     NaN     NaN
8   0.08    77      99
9   NaN     NaN     NaN
10  NaN     NaN     NaN
11  NaN     NaN     NaN
12  0.12    80      98

Auquel je peux ensuite faire appel

df = df.interpolate()

Ce qui donnerait quelque chose comme ça (je compose les chiffres ici):

    Time    Pulse   O2
0   0.00    76      99
1   0.01    76      99
2   0.02    75      99
3   0.03    74      100
4   0.04    74      100
5   0.05    75      100
6   0.06    76      99
7   0.07    77      99
8   0.08    77      99
9   0.09    77      99
10  0.10    78      98
11  0.11    79      98
12  0.12    80      98

J'ai essayé d'utiliser une technique iterrows en insérant le cadre df_ins après chaque ligne. Mais mon index a été éjecté pendant l'itération. J'ai aussi essayé de découper df et de concaténer les tranches df et df_ins, mais encore une fois, les index ont été rejetés par la boucle.

Quelqu'un a-t-il des recommandations sur la façon de procéder efficacement?

4
chris-ulmy 13 janv. 2021 à 23:49

2 réponses

Meilleure réponse

Utilisez resample ici (remplacez ffill par le comportement souhaité, peut-être déranger avec interpolate)

df["Time"] = pd.to_timedelta(df["Time"], unit="S")
df.set_index("Time").resample("0.01S").ffill()

                 Pulse   O2
Time
00:00:00            76   99
00:00:00.010000     76   99
00:00:00.020000     76   99
00:00:00.030000     76   99
00:00:00.040000     74  100
00:00:00.050000     74  100
00:00:00.060000     74  100
00:00:00.070000     74  100
00:00:00.080000     77   99
00:00:00.090000     77   99
00:00:00.100000     77   99
00:00:00.110000     77   99
00:00:00.120000     80   98

Si vous voulez interpoler:

df.set_index("Time").resample("0.01S").interpolate()

                 Pulse      O2
Time
00:00:00         76.00   99.00
00:00:00.010000  75.50   99.25
00:00:00.020000  75.00   99.50
00:00:00.030000  74.50   99.75
00:00:00.040000  74.00  100.00
00:00:00.050000  74.75   99.75
00:00:00.060000  75.50   99.50
00:00:00.070000  76.25   99.25
00:00:00.080000  77.00   99.00
00:00:00.090000  77.75   98.75
00:00:00.100000  78.50   98.50
00:00:00.110000  79.25   98.25
00:00:00.120000  80.00   98.00
3
user3483203 13 janv. 2021 à 21:00

Je pense que l'utilisation de np.linspace et de processus par colonne devrait être plus rapide que d'interpoler (si votre colonne Time n'est pas exactement au format heure):

import numpy as np
import pandas as pd

new_dict = {}
for c in df.columns:
    arr = df[c]
    ret = []
    for i in range(1, len(arr)):
        ret.append(np.linspace(arr[i-1], arr[i], 4, endpoint=False)[1:])
    new_dict[c] = np.concatenate(ret)
pd.concat([df, pd.DataFrame(new_dict)]).sort_values('Time').reset_index(drop=True)
    Time    Pulse   O2
0   0.00    76.00   99.00
1   0.01    75.50   99.25
2   0.02    75.00   99.50
3   0.03    74.50   99.75
4   0.04    74.00   100.00
5   0.05    74.75   99.75
6   0.06    75.50   99.50
7   0.07    76.25   99.25
8   0.08    77.00   99.00
9   0.09    77.75   98.75
10  0.10    78.50   98.50
11  0.11    79.25   98.25
12  0.12    80.00   98.00
1
Z Li 13 janv. 2021 à 20:59
65709568