2017-03-24 6 views
0

인덱스 팬더 데이터 프레임으로 변환하려는 알 수없는 데이터 행을 반환하는 생성기가 있습니다. 내가 아는 가장 빠른 방법은 디스크에 CSV를 쓰고 'read_csv'를 통해 다시 구문 분석하는 것입니다. 빈 데이터 프레임을 만든 다음 끊임없이 새로운 행을 추가하는 것이 효율적이지 않다는 것을 알고 있습니다. 얼마나 많은 행이 반환 될지 모르기 때문에 미리 크기가 조정 된 데이터 프레임을 만들 수 없습니다. 디스크에 쓰지 않고 반복자 출력을 판다 데이터 프레임으로 변환하는 방법이 있습니까?파이썬 반복자 출력을 팬더 데이터 프레임으로 변환하는 가장 빠른 방법

+1

디스크에 쓰지 마십시오. 대신 그것을 튜플 목록으로 가져 와서 목록을'pd.DataFrame'으로 전달하십시오. – James

답변

1

트릭을 일반적으로하는 것처럼 보이십니까?

def make_equal_length_cols(df, new_iter, col_name): 
    # convert the generator to a list so we can append 
    new_iter = list(new_iter) 
    # if the passed generator (as a list) has fewer elements that the dataframe, we ought to add NaN elements until their lengths are equal 
    if len(new_iter) < df.shape[0]: 
     new_iter += [np.nan]*(df.shape[0]-len(new_iter)) 
    else: 
     # otherwise, each column gets n new NaN rows, where n is the difference between the number of elements in new_iter and the length of the dataframe 
     new_rows = [{c: np.nan for c in df.columns} for _ in range((len(new_iter)-df.shape[0]))] 
     new_rows_df = pd.DataFrame(new_rows) 
     df = df.append(new_rows_df).reset_index(drop=True) 
    df[col_name] = new_iter 
    return df 

테스트를 아웃 :

make_equal_length_cols(df, (x for x in range(20)), 'new') 
Out[22]: 
     A B new 
0 0.0 0.0 0 
1 1.0 1.0 1 
2 2.0 2.0 2 
3 3.0 3.0 3 
4 4.0 4.0 4 
5 5.0 5.0 5 
6 6.0 6.0 6 
7 7.0 7.0 7 
8 8.0 8.0 8 
9 9.0 9.0 9 
10 NaN NaN 10 
11 NaN NaN 11 
12 NaN NaN 12 
13 NaN NaN 13 
14 NaN NaN 14 
15 NaN NaN 15 
16 NaN NaN 16 
17 NaN NaN 17 
18 NaN NaN 18 
19 NaN NaN 19 

그리고 전달 된 발전기가 dataframe보다 짧은 경우 그것은 또한 작동합니다

make_equal_length_cols(df, (x for x in range(5)), 'new') 
Out[26]: 
    A B new 
0 0 0 0.0 
1 1 1 1.0 
2 2 2 2.0 
3 3 3 3.0 
4 4 4 4.0 
5 5 5 NaN 
6 6 6 NaN 
7 7 7 NaN 
8 8 8 NaN 
9 9 9 NaN 

편집 : 제거 된 행 단위 pandas.DataFrame.append 전화, 별도의 데이터 프레임을 구성하여 한 번에 추가 할 수 있습니다. 타이밍 :

새로 추가합니다

%timeit make_equal_length_cols(df, (x for x in range(10000)), 'new') 
10 loops, best of 3: 40.1 ms per loop 

올드 추가합니다

very slow... 
1

가 반복적으로 판다 데이터 프레임에 추가는 최선의 해결책이 아닙니다. 데이터를 목록으로 작성한 다음 pd.DataFrame에 전달하는 것이 좋습니다. 여기

import random 
import pandas as pd 

alpha = list('abcdefghijklmnopqrstuvwxyz') 

우리는 발전기를 만들 목록을 구성하는 데 사용할 다음 dataframe 생성자에 전달 :

%%timeit 
gen = ((random.choice(alpha), random.randint(0,100)) for x in range(10000)) 
my_data = [x for x in gen] 
df = pd.DataFrame(my_data, columns=['letter','value']) 

# result: 1 loop, best of 3: 373 ms per loop 

이 상당히 빠르게 발전기를 만드는 것보다, 빈 dataframe를 구성 행을 추가하면 다음과 같이 표시됩니다.

%%timeit 
gen = ((random.choice(alpha), random.randint(0,100)) for x in range(10000)) 
df = pd.DataFrame(columns=['letter','value']) 
for tup in gen: 
    df.loc[df.shape[0],:] = tup 

# result: 1 loop, best of 3: 13.6 s per loop 

10000 행을 구성하는 데 13 초의 시간이 소요됩니다.

관련 문제