2016-11-04 154 views
1

我非常肯定這有一個非常簡單的解決方案,我只是沒有意識到它。然而...通過另一個數據幀中的值列表拆分熊貓數據幀

我有一個高頻數據的數據幀。調用這個數據框A.我還有一個單獨的低頻率分界點列表,稱這個B.我想給A添加一列,如果A的時間戳列在B [0]和B [1 ],2如果它在B [1]和B [2]之間,依此類推。

如上所述,這可能非常微不足道,而我在這一個小時就沒有意識到它。

回答

2

這是一個使用列表理解的快速和骯髒的方法。

>>> 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

使用searchsorted

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

對於A['timestamp']每個值,則返回的索引值。該索引指示B['timestamp']中的排序值中的哪個值將從A插入到B以便維持排序順序。

例如,

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) 

產生

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 

因此,時間戳0.896705是在組0因爲它是前B['timestamp'][0](即1.739869)。時間戳2.410220在組1中,因爲它大於B['timestamp'][0](即1.739869)但小於B['timestamp'][1](即2.467790)。


你也應該決定做什麼,如果在A['timestamp']值正好等於在B['timestamp']截止值之一。使用

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

,如果你想searchsorted返回iB['timestamp'][i] <= A['timestamp'][i] <= B['timestamp'][i+1]。使用

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

如果你想在這種情況下searchsorted返回i+1。如果您未指定side,則默認使用side='left'