2016-05-03 29 views
9

Tôi đang thêm hàng vào một DataFrame gấu trúc trong vòng lặp for, nhưng ở cuối khung dữ liệu luôn trống. Tôi không muốn thêm các hàng vào một mảng và sau đó gọi cấu trúc DataFrame, vì vòng lặp thực tế của tôi xử lý rất nhiều dữ liệu. Tôi cũng đã thử pd.concat mà không thành công. Bất cứ ai có thể làm nổi bật những gì tôi đang thiếu để làm cho tuyên bố phụ thêm hoạt động? Dưới đây là ví dụ giả:Sử dụng gấu trúc .append within for loop

import pandas as pd 
import numpy as np 

data = pd.DataFrame([]) 

for i in np.arange(0, 4): 
    if i % 2 == 0: 
     data.append(pd.DataFrame({'A': i, 'B': i + 1}, index=[0]), ignore_index=True) 
    else: 
     data.append(pd.DataFrame({'A': i}, index=[0]), ignore_index=True) 

print data.head() 

Empty DataFrame 
Columns: [] 
Index: [] 
[Finished in 0.676s] 

Trả lời

6

Bạn cần đặt biến data bằng khung dữ liệu được nối thêm. Không giống như các phương pháp append trên một danh sách python gấu trúc append không xảy ra ở vị trí

import pandas as pd 
import numpy as np 

data = pd.DataFrame([]) 

for i in np.arange(0, 4): 
    if i % 2 == 0: 
     data = data.append(pd.DataFrame({'A': i, 'B': i + 1}, index=[0]), ignore_index=True) 
    else: 
     data = data.append(pd.DataFrame({'A': i}, index=[0]), ignore_index=True) 

print(data.head()) 

    A B 
0 0 1.0 
1 2 3.0 
2 3 NaN 
+0

Cảm ơn mà làm việc! Kinda ngớ ngẩn mà tôi không nghĩ về điều đó. – chizze

13

Mỗi lần bạn gọi thêm, Pandas trả về một bản sao của dataframe ban đầu cộng với hàng mới của bạn. Điều này được gọi là bản sao bậc hai, và nó là một hoạt động O (N^2) sẽ nhanh chóng trở nên rất chậm (đặc biệt là vì bạn có nhiều dữ liệu).

Trong trường hợp của bạn, tôi khuyên bạn nên sử dụng danh sách, thêm vào danh sách và sau đó gọi hàm tạo dataframe.

a_list = [] 
b_list = [] 
for data in my_data: 
    a, b = process_data(data) 
    a_list.append(a) 
    b_list.append(b) 
df = pd.DataFrame({'A': a_list, 'B': b_list}) 
del a_list, b_list 

Thời gian

%%timeit 
data = pd.DataFrame([]) 
for i in np.arange(0, 10000): 
    if i % 2 == 0: 
     data = data.append(pd.DataFrame({'A': i, 'B': i + 1}, index=[0]), ignore_index=True) 
else: 
    data = data.append(pd.DataFrame({'A': i}, index=[0]), ignore_index=True) 
1 loops, best of 3: 6.8 s per loop 

%%timeit 
a_list = [] 
b_list = [] 
for i in np.arange(0, 10000): 
    if i % 2 == 0: 
     a_list.append(i) 
     b_list.append(i + 1) 
    else: 
     a_list.append(i) 
     b_list.append(None) 
data = pd.DataFrame({'A': a_list, 'B': b_list}) 
100 loops, best of 3: 8.54 ms per loop 
+0

Được rồi, vì vậy lưu nó vào một mảng và sau đó gọi DataFrame thực sự nhanh hơn sau đó. Cảm ơn! – chizze

2

Bạn có thể xây dựng dataframe bạn mà không cần một vòng lặp:

n = 4 
data = pd.DataFrame({'A': np.arange(n)}) 
data['B'] = np.NaN 
data.loc[data['A'] % 2 == 0, 'B'] = data['A'] + 1 

Mục đích:

n = 10000 

Đây là một chút nhanh hơn:

%%timeit 
data = pd.DataFrame({'A': np.arange(n)}) 
data['B'] = np.NaN 
data.loc[data['A'] % 2 == 0, 'B'] = data['A'] + 1 

100 loops, best of 3: 3.3 ms per loop 

vs

%%timeit 
a_list = [] 
b_list = [] 
for i in np.arange(n): 
    if i % 2 == 0: 
     a_list.append(i) 
     b_list.append(i + 1) 
    else: 
     a_list.append(i) 
     b_list.append(None) 
data1 = pd.DataFrame({'A': a_list, 'B': b_list}) 

100 loops, best of 3: 12.4 ms per loop