2017-11-17 2 views
0

약간의 특이한 문제가 있습니다. 샘플링하려고하는 매우 큰 데이터 프레임이 있습니다.n 번째 값마다 또는 n 번째 값과 가장 근접한 매칭 값을 샘플링하는 팬더

x,y 
1,'a' 
1,'b' 
1,'c' 
3,'a' 
3,'b' 
3,'c' 
6,'a' 
6,'b' 
6,'c' 

내가 'X'의 값에 따라 샘플링 할 :

내 데이터는 다음과 같이 (두 개의 열 x와 y)를 보인다. 모든 32 x 값 중에서 하나의 샘플을 원합니다. (x 값의 변화에 ​​따라, 1과 32 사이의 x 값이 하나라도 1에서 32까지 한 번 샘플링하고 싶습니다.)

다음과 같이하고 싶습니다. df[df['x'] % 32 == 0]. 문제는 x 값이 반드시 균등하게 간격을 두지 않는다는 것입니다 ("대략"이지만 주어진 예와 같이 항상 그런 것은 아닙니다). 예를 들어 특정 하위 문제의 x 값이 모두 홀수 인 경우 위의 샘플링은 빈 데이터 프레임을 반환합니다. 사실, 32 'x마다 한 번 샘플링하거나 32 번째 값에 가장 가까운 값을 취하고 싶습니다. 가장 가까운 값을 근사값으로 사용할 수 있습니다. 예를 들어, 다음 값을 사용할 수 있습니다.

그래서 일련의 X가 [0, 10, 32, 39, 64, 70, 73, 74, 97, 100, 110, 129] 인 경우 x 값이 [0, 32, 64, 97, 129] 인 행을 샘플링하고 싶습니다.

데이터 프레임이 종종 매우 크기 때문에 이상적으로이 작업을 벡터화 할 수도 있습니다.

답변

1
df = pd.DataFrame({'x': [1, 1, 1, 3, 3, 3, 6, 6, 6], 
        'y': ['a', 'b', 'c'] * 3}) 

x = [0, 10, 32, 39, 64, 70, 73, 74, 97, 100, 110, 129] 
spacer = 32 

X = pd.Series(x) 
# For each value `n` in the range 0, 32, 64, ..., 129, find the index location of the 
# nearest value in X via `X.sub(n).abs().idxmin()`. Then use these index locations 
# to find the actual target values in X via `loc`. 
target_vals = X.loc[[X.sub(n).abs().idxmin() 
        for n in xrange(0, x[-1], spacer)]].tolist() # `range` in Python 3. 
>>> target_vals 
[0, 32, 64, 97, 129] 

# Sample the target values, taking a sample size of 1. 
df[df['x'].isin(target_vals)].groupby('x').apply(lambda group: group.sample(1)) 
1

동적으로 다음 그룹을 만들고 'X'의 모든 32 개 값에 대해 하나 개의 기록을 얻을 수 sample(1)groupby을 사용하는 pd.cut를 사용하는 지능형리스트와 쓰레기통을 만들 수 있습니다.

df = pd.DataFrame({'X':np.random.randint(0, 100, 5000),'Y':np.random.choice(list('ABCDEF'),5000)}) 

bins = [i for i in np.arange(df.X.min(), df.X.max(), 32)] + [np.inf] 

df.groupby(pd.cut(df.X,bins=bins), as_index=False).apply(lambda x: x.sample(1).values) 

출력 :

[[15 'F'] 
[51 'A'] 
[90 'C'] 
[98 'A']]