2017-10-03 4 views
1

J'ai un dataframe avec trois clumns:
1. ID (int64): Object ID
2. DATETIME (datetime64 [ns]): Date et heure les quatre dernières valeurs de l'objet ont été collectées. La fréquence peut être inférieure ou supérieure à une heure. La valeur de certains intervalles de 15mn peut être manquante lorsque deux collectes successives sont séparées d'une heure et 15 minutes ou plus.
3. VALEURS (objet chaîne): valeurs séparées par des virgules pour quatre valeurs de l'objet. Chaque valeur est la valeur de l'objet au cours des 15 dernières minutes. Exemple lorsque les valeurs collectées à 10h sont "0,1,2,3", cela signifie que la valeur de l'objet était 0 entre 9h45 et 10h, 1 entre 9h30 et 9h45, etc.pandas géants - Comment sélectionner la valeur et suréchantillonner correspondante pour les nouvelles cellules

Je souhaite rééchantillonner cette image avec une fréquence de 15 minutes et avoir pour chaque intervalle de 15 minutes la valeur correspondante sans boucle for explicite (ou avec le minimum de boucles) car il s'agit d'un énorme dataframe et la boucle rendra l'exécution trop longue ...

Voici un échantillon de ce que j'ai pour un seul objet:

ID,COLLECTION_DATETIME,VALUES 
10000,2017-09-13 10:30:00,"2,1,0,3" 
10000,2017-09-13 11:00:00,"6,5,2,1" 
10000,2017-09-13 12:15:00,"0,0,0,2" 

Et voici le résultat que je veux obtenir:

ID,COLLECTION_DATETIME,VALUE 
10000,2017-09-13 09:45:00,3 
10000,2017-09-13 10:00:00,0 
10000,2017-09-13 10:15:00,1 
10000,2017-09-13 10:30:00,2 
10000,2017-09-13 10:45:00,5 
10000,2017-09-13 11:00:00,6 
10000,2017-09-13 11:15:00,NaN 
10000,2017-09-13 11:30:00,2 
10000,2017-09-13 11:45:00,0 
10000,2017-09-13 12:00:00,0 
10000,2017-09-13 12:15:00,0 

Je suppose que cela peut être fait en utilisant la colonne « COLLECTION_DATETIME » comme indice et rééchantillonner avec une fréquence de 15 minutes, la division colonne « valeurs » (df [ « »] VALEURS. Str.split (« », développez = True)) et en le transposant, affectant d'une manière ou d'une autre le résultat à une nouvelle colonne de df.resample ('15min') et supprimant les intervalles en double mais je ne peux toujours pas le faire Toute idée ou indication aiderait.

+0

Pourquoi 'Nan' au lieu de 0? Toutes les valeurs sont de taille 4 – erasmortg

+0

Parce que la valeur de l'objet dans cet intervalle n'a pas été collectée et ne peut pas être 0. Toute autre valeur inutilisée (disons 999) peut être utilisée à la place de Nan. – JustForFun

+0

10000,2017-09-13 10:30:00, "2,1,0,3" signifie que cet objet avait la valeur 2 entre 10:15 et 10:30 (donc la valeur souhaitée pour DATE_TIME 2017-09-13 10 : 30: 00 dans la zone de données Upsampled doit être 2 (valeur de l'intervalle unique de 15 minutes)), 1 entre 10:00 et 10:15, 0 entre 09:45 et 10:00 et 3 entre 09:30 et 09:45 (==> c'est correct ci-dessus) – JustForFun

Répondre

0

Vous pouvez utiliser:

#change order of values 
df['VALUES'] = df['VALUES'].str[::-1] 
#repeat index by len of splitted values 
a = df['VALUES'].str.split(',') 
l = a.str.len() 
#flatten column VALUES 
df = df.loc[df.index.repeat(l)].assign(VALUES=np.concatenate(a)) 
#convert index to column and create unique index 
df = df.reset_index(drop=True) 

print (df) 
    index  ID COLLECTION_DATETIME VALUES 
0  0 10000 2017-09-13 10:30:00  3 
1  0 10000 2017-09-13 10:30:00  0 
2  0 10000 2017-09-13 10:30:00  1 
3  0 10000 2017-09-13 10:30:00  2 
4  1 10000 2017-09-13 11:00:00  1 
5  1 10000 2017-09-13 11:00:00  2 
6  1 10000 2017-09-13 11:00:00  5 
7  1 10000 2017-09-13 11:00:00  6 
8  2 10000 2017-09-13 12:15:00  2 
9  2 10000 2017-09-13 12:15:00  0 
10  2 10000 2017-09-13 12:15:00  0 
11  2 10000 2017-09-13 12:15:00  0 

#subtract timedelta by count each datetime 
a = pd.to_timedelta(df[::-1].groupby('index').cumcount() * 15, unit='T') 
df['COLLECTION_DATETIME'] = df['COLLECTION_DATETIME'] - a 
df = df.set_index('COLLECTION_DATETIME').drop('index', axis=1) 
#create unique DatetimeIndex and convert frequency 
df = df.groupby(level=0).first().asfreq('15min') 
#replace NaN by forward filling 
df['ID'] = df['ID'].ffill().astype(int) 
print (df) 
         ID VALUES 
COLLECTION_DATETIME    
2017-09-13 09:45:00 10000  3 
2017-09-13 10:00:00 10000  0 
2017-09-13 10:15:00 10000  1 
2017-09-13 10:30:00 10000  2 
2017-09-13 10:45:00 10000  5 
2017-09-13 11:00:00 10000  6 
2017-09-13 11:15:00 10000 NaN 
2017-09-13 11:30:00 10000  2 
2017-09-13 11:45:00 10000  0 
2017-09-13 12:00:00 10000  0 
2017-09-13 12:15:00 10000  0 
+0

Merci beaucoup @jezrael – JustForFun

+0

Enfin, cela fonctionne bien avec un seul ID dans la base de données (comme dans l'exemple) mais avec de nombreux ID cela ne produira pas un résultat correct: la partie groupby (niveau = 0) .first() ne gardez que le premier identifiant. Est-il possible d'avoir le résultat pour plusieurs ID sans boucler sur df ['ID']. Unique() et concaturer tous les résultats pour tous les ID? – JustForFun

+0

Malheureusement, pas parce que les pandas ne le supporte pas :(Besoin toujours index unique. – jezrael