2016-11-04 4 views
1

Ich bin mir ziemlich sicher, dass es eine wirklich einfache Lösung dafür gibt und ich merke es nur nicht. Jedoch ...Teilen Sie einen Pandas Datenrahmen durch eine Liste von Werten aus einem anderen Datenrahmen

Ich habe einen Datenrahmen von Hochfrequenzdaten. Nenne diesen Datenrahmen A. Ich habe auch eine separate Liste von Abgrenzungspunkten mit viel niedrigeren Frequenzen, rufe dieses B. Ich möchte eine Spalte an A anhängen, die 1 anzeigen würde, wenn die Zeitstempelspalte von A zwischen B [0] und B [1 liegt ], 2 wenn es zwischen B [1] und B [2] ist, und so weiter.

Wie gesagt, es ist wahrscheinlich unglaublich trivial, und ich merke es nur zu dieser späten Stunde nicht.

Antwort

2

Hier ist ein schneller und dreckiger Ansatz mit einem Listenverständnis.

>>> df = pd.DataFrame({'A': np.arange(1, 3, 0.2)}) 

>>> A = df.A.values.tolist() 
A: [1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.5, 2.6, 2.8] 

>>> B = np.arange(0, 3, 1).tolist() 
B: [0, 1, 2] 

>>> BA = [k for k in range(0, len(B)-1) for a in A if (B[k]<=a) & (B[k+1]>a) or (a>max(B))] 
BA: [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 
2

Verwenden searchsorted:

A['group'] = B['timestamp'].searchsorted(A['timestamp']) 

für jeden Wert in A['timestamp'] wird ein Indexwert zurückgegeben. Dieser Index gibt an, wo unter den sortierten Werten in B['timestamp'] dieser Wert von A in B eingefügt werden würde, um sortierte Reihenfolge beizubehalten.

Zum Beispiel

import numpy as np 
import pandas as pd 
np.random.seed(2016) 

N = 10 
A = pd.DataFrame({'timestamp':np.random.uniform(0, 1, size=N).cumsum()}) 
B = pd.DataFrame({'timestamp':np.random.uniform(0, 3, size=N).cumsum()}) 
# timestamp 
# 0 1.739869 
# 1 2.467790 
# 2 2.863659 
# 3 3.295505 
# 4 5.106419 
# 5 6.872791 
# 6 7.080834 
# 7 9.909320 
# 8 11.027117 
# 9 12.383085 

A['group'] = B['timestamp'].searchsorted(A['timestamp']) 
print(A) 

ergibt

timestamp group 
0 0.896705  0 
1 1.626945  0 
2 2.410220  1 
3 3.151872  3 
4 3.613962  4 
5 4.256528  4 
6 4.481392  4 
7 5.189938  5 
8 5.937064  5 
9 6.562172  5 

Somit wird der Zeitstempel ist in 0.896705 Gruppe 0 weil es vor B['timestamp'][0] kommt (d.h. 1.739869). Der Zeitstempel 2.410220 ist in Gruppe 1, weil er größer ist als B['timestamp'][0] (d.h. 1.739869), aber kleiner als B['timestamp'][1] (d.h. 2.467790).


Sie sollten auch entscheiden, was in A['timestamp'] wenn ein Wert zu tun, ist genau gleich einer der Cutoff-Werte in B['timestamp']. Verwenden Sie

B['timestamp'].searchsorted(A['timestamp'], side='left') 

wenn Sie searchsorted wollen i wenn B['timestamp'][i] <= A['timestamp'][i] <= B['timestamp'][i+1] zurückzukehren. Verwenden Sie

B['timestamp'].searchsorted(A['timestamp'], side='right') 

wenn Sie searchsorted wollen i+1 in dieser Situation zurückzukehren. Wenn Sie side nicht angeben, wird standardmäßig side='left' verwendet.

Verwandte Themen