2016-09-30 2 views
3

I 다음 팬더 DataFrame 가지고"간격"을 위해 pandas DataFrame의 여러 열을 일치시키는 방법은 무엇입니까?

import pandas as pd 
df = pd.DataFrame('filename.csv') 
print(df) 

order start end value  
1  1342 1357 category1 
1  1459 1489 category7 
1  1572 1601 category23 
1  1587 1599 category2 
1  1591 1639 category1 
.... 
15  792  813 category13 
15  892  913 category5 
.... 

그래서 order 열이 많은 각 행 및 각 행에 endstart의 범위/간격이 것을 포함이다. 각 행에 특정 value (예 : category1, category2 등)이라는 레이블이 지정되어 있습니다.

이제 key_df이라는 또 다른 데이터 프레임이 있습니다.

import pandas as pd 
key_df = pd.DataFrame(...) 
print(key_df) 

order start end value  
1  1284 1299 category4 
1  1297 1309 category9 
1  1312 1369 category3 
1  1345 1392 category29 
1  1371 1383 category31 
.... 
1  1471 1501 category31 
... 

내 목표는 key_df dataframe을 가지고 간격이 원래 dataframe df의 행과 일치 start:end 여부를 확인하는 것입니다 : 그것은 기본적으로 동일한 형식입니다. 이 경우 df의 행은 key_df 데이터 프레임의 value 값으로 레이블되어야합니다. 위의 예에서

의 dataframe df는 다음과 같이 끝날 것입니다 : 당신이 간격 1::1345-1392key_df, 행

1  1345 1392 category29 

보면 간격에 빠진다 때문에

order start end value  key_value 
1  1342 1357 category1 category29 
1  1459 1489 category7 category31 
.... 

입니다 1::1342-1357 원래 df입니다. 마찬가지로, key_df 행 :

1  1471 1501 category31 

df에서 두 번째 행에 해당

1  1459 1489 category7 category31 

내가 완전히 확실하지 않다

(1) 팬더

에서이 작업을 수행하는 방법에

(2) 팬더에서이를 효율적으로 조절하는 방법

if 문으로 시작할 수 있습니다.

if df.order == key_df.order: 
    # now check intervals...somehow 

그러나 이것은 데이터 프레임 구조를 이용하지 않습니다. 그런 다음 하나씩 간격으로 확인해야합니다 (예 : (df.start =< key_df.start) && (df.end => key_df.end)).

막혔습니다. 팬더에서 "간격"으로 여러 열을 일치시키는 가장 효율적인 방법은 무엇입니까?

답변

1

당신은 boolean indexingmerge을 사용할 수 있습니다 (이 조건이 충족되는 경우 다음 간단 새 열입니다 만들기), 그러나 DataFrames가 큰 경우, 스케일링은 문제가있다 :

df1 = pd.merge(df, key_df, on='order', how='outer', suffixes=('','_key')) 
df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] 
df1 = pd.merge(df, df1, on=['order','start','end', 'value'], how='left') 
print (df1) 
    order start end  value start_key end_key value_key 
0  1 1342 1357 category1  1345.0 1392.0 category29 
1  1 1342 1357 category1  1371.0 1383.0 category31 
2  1 1342 1357 category1  1471.0 1501.0 category31 
3  1 1459 1489 category7  1471.0 1501.0 category31 
4  1 1572 1601 category23  NaN  NaN   NaN 
5  1 1587 1599 category2  NaN  NaN   NaN 
6  1 1591 1639 category1  NaN  NaN   NaN 
7  15 792 813 category13  NaN  NaN   NaN 
8  15 892 913 category5  NaN  NaN   NaN 
: 코멘트에 의해

df1 = pd.merge(df, key_df, on='order', how='outer', suffixes=('','_key')) 
df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] 
print (df1) 
    order start end  value start_key end_key value_key 
3  1 1342 1357 category1  1345.0 1392.0 category29 
4  1 1342 1357 category1  1371.0 1383.0 category31 
5  1 1342 1357 category1  1471.0 1501.0 category31 
11  1 1459 1489 category7  1471.0 1501.0 category31 

편집

+0

여기에 오류가 나타났습니다. 주어진 행에 대해 'value_key'가 없다면, 이것은 버려 질 것입니다. 우리의 목적을 위해서,'df '의 모든 행은 좋다. 아무 것도 버려 져야한다. 주어진 행에 'value_key'가 적용되지 않으면 (즉,간격에 해당하지 않음), "NaN"을 기록해야합니다. – ShanZhengYang

+0

내 코드에 왼쪽 조인과 함께'merge'를 추가해야합니까? 'df1 = pd.merge (df, df1, on = [ 'order', 'start', 'end', 'value'], how = 'left')'? – jezrael

+0

답해 주셔서 감사합니다. 나는 이것이 대략 100 MB 크기의 데이터 프레임에 대해 확장 할 수 없다는 것을 언급해야한다. 나는'MemoryError'를 얻는다. 어떤 아이디어를 어떻게 확장 성을 높일 수 있을까요? 병합 대신에 for 루프가 많이 있습니까? 여기에 오류가 있습니다 : 'File "pandas/src/join.pyx", 187 행, pandas.algos.full_outer_join''(pandas/algos.c : 61680)' '파일 "pandas/src/join.pyx" , line 196,' 'pandas.algos._get_result_indexer (pandas/algos.c : 61978)' 'MemoryError' – ShanZhengYang

관련 문제