2017-03-07 5 views
2

두 데이터 프레임이 있는데, 예를 들어 dfmap_dum이라고합시다. 다음은 df입니다.팬더는 새로운 열을 추가하는 대신 다른 조건을 적용합니다.

>>> print(df) 
    sales 
0  5 
1  10 
2  9 
3  7 
4  1 
5  1 
6  -1 
7  2 
8  9 
9  8 
10  1 
11  3 
12  10 
13  -2 
14  8 
15  5 
16  9 
17  6 
18  10 
19  -1 
20  5 
21  3 

여기는 map_dum입니다.

>>> print(map_dum) 
    class more_than_or_equal_to less_than 
0  -1     -1000   0 
1  1      0   2 
2  2      2   4 
3  3      4   6 
4  4      6   8 
5  5      8   10 
6  6      10  1000 

내 목표는 df에 새 열, 열 class를 추가하는 것입니다. 이렇게하려면 df['sales']의 값을 map_dum 사이의 값으로 설정해야합니다. 예를 들어 df['sales'], 5의 첫 번째 행에 대해 class을 알고 싶다면 class은 3이됩니다. 최종 출력은 다음과 같습니다. 내 데이터 세트가 매우 큰이기 때문에

>>> print(df) 
    sales class 
0  5  3 
1  10  6 
2  9  5 
3  7  4 
4  1  1 
5  1  1 
6  -1  -1 
7  2  2 
8  9  5 
9  8  5 
10  1  1 
11  3  2 
12  10  6 
13  -2  -1 
14  8  5 
15  5  3 
16  9  5 
17  6  4 
18  10  6 
19  -1  -1 
20  5  3 
21  3  2 

현재, 나는이 문제를 해결하기 위해 apply을 사용하고, 그러나, 그것은 매우 느립니다.

def add_class(sales, mapping, lower_limit, upper_limit): 
    result = mapping.loc[((mapping[lower_limit]<=sales)&(mapping[upper_limit]>sales)), 'class'].tolist()[0] 
    return result 

df['class'] = df['sales'].apply(lambda sales: add_class(sales, map_dum, 'more_than_or_equal_to', 'less_than')) 

필자의 경우 성능이 중요합니다. class 열을 df에 추가하면 벡터화 솔루션과 같은 기준을 위반하지 않습니다. 어떤 도움을 주셔서 감사합니다!

답변

3

난 당신이 cut 필요하다고 생각 : map_dum 사용에서 동적 추가 값에 대한

bins = [-1000, 0, 2, 4, 6, 8, 10, 1000] 
labels=[-1,1,2,3,4,5,6] 
df['class'] = pd.cut(df['sales'], bins=bins, labels=labels, right=False) 
print (df) 
    sales class 
0  5  3 
1  10  6 
2  9  5 
3  7  4 
4  1  1 
5  1  1 
6  -1 -1 
7  2  2 
8  9  5 
9  8  5 
10  1  1 
11  3  2 
12  10  6 
13  -2 -1 
14  8  5 
15  5  3 
16  9  5 
17  6  4 
18  10  6 
19  -1 -1 
20  5  3 
21  3  2 

:

bins = [map_dum['more_than_or_equal_to'].iat[0]] + map_dum['less_than'].tolist() 
labels= map_dum['class'] 
df['class'] = pd.cut(df['sales'], bins=bins, labels=labels, right=False) 
print (df) 
+0

감사합니다 많이! 실제로 더 빠르고 청소기입니다! – arnold