2012-10-15 46 views
7

Tôi mới tham gia gấu trúc và tôi đang cố gắng đọc một tệp được định dạng lạ vào một DataFrame. Các tập tin ban đầu trông như thế này:Mở rộng hiệu quả các dòng từ gấu trúc DataFrame

; No Time Date MoistAve MatTemp TDRConduct TDRAve DeltaCount tpAve Moist1 Moist2 Moist3 Moist4 TDR1 TDR2 TDR3 TDR4 
1 11:38:17 11.07.2012 11.37 48.20 5.15 88.87 15 344.50 11.84 11.35 11.59 15.25 89.0 89.0 89.0 88.0 
2 11:38:18 11.07.2012 11.44 48.20 5.13 88.88 2 346.22 12.08 11.83 -1.00 -1.00 89.0 89.0 -1.0 -1.0 
3 11:38:19 11.07.2012 11.10 48.20 4.96 89.00 3 337.84 11.83 11.59 10.62 -1.00 89.0 89.0 89.0 -1.0 
4 11:38:19 11.07.2012 11.82 48.20 5.54 88.60 3 355.92 11.10 13.54 12.32 -1.00 89.0 88.0 88.0 -1.0 

tôi quản lý để có được một DataFrame có cấu trúc như nhau với:

In [42]: date_spec = {'FetchTime': [1, 2]} 

In [43]: df = pd.read_csv('MeasureCK32450-20120711114050.mck', header=7, sep='\s\s+', 
          parse_dates=date_spec, na_values=['-1.0', '-1.00']) 

In [44]: df 
Out[52]: 
       FetchTime ; No MoistAve MatTemp TDRConduct TDRAve DeltaCount tpAve Moist1 Moist2 Moist3 Moist4 TDR1 TDR2 TDR3 TDR4 
0 2012-11-07 11:38:17  1  11.37  48.2  5.15 88.87   15 344.50 11.84 11.35 11.59 15.25 89 89 89 88 
1 2012-11-07 11:38:18  2  11.44  48.2  5.13 88.88   2 346.22 12.08 11.83  NaN  NaN 89 89 NaN NaN 
2 2012-11-07 11:38:19  3  11.10  48.2  4.96 89.00   3 337.84 11.83 11.59 10.62  NaN 89 89 89 NaN 
3 2012-11-07 11:38:19  4  11.82  48.2  5.54 88.60   3 355.92 11.10 13.54 12.32  NaN 89 88 88 NaN 

Nhưng bây giờ tôi phải mở rộng mỗi dòng DataFrame này

.... Moist1 Moist2 Moist3 Moist4 TDR1 TDR2 TDR3 TDR4 
1 .... 11.84 11.35 11.59 15.25 89 89 89 88 
2 .... 12.08 11.83  NaN  NaN 89 89 NaN NaN 

thành bốn dòng (với ba chỉ mục No, FetchTime và MeasureNo):

        .... Moist TDR 
No   FetchTime MeasureNo 
0 2012-11-07 11:38:17   1 .... 11.84 89 # from line 1, Moist1 and TDR1 
1        2 .... 11.35 89 # from line 1, Moist2 and TDR2 
2        3 .... 11.59 89 # from line 1, Moist3 and TDR3 
3        4 .... 15.25 88 # from line 1, Moist4 and TDR4 
4 2012-11-07 11:38:18   1 .... 12.08 89 # from line 2, Moist1 and TDR1 
5        2 .... 11.83 89 # from line 2, Moist2 and TDR2 
6        3 .... NaN NaN # from line 2, Moist3 and TDR3 
7        4 .... NaN NaN # from line 2, Moist4 and TDR4 

bằng cách bảo quản các cột khác và MOST quan trọng, giữ nguyên thứ tự của các mục nhập. Tôi biết tôi có thể lặp qua từng dòng với for row in df.iterrows(): ... nhưng tôi đọc đây là không phải là rất nhanh. Cách tiếp cận đầu tiên của tôi là thế này:

In [54]: data = [] 
In [55]: for d in range(1,5): 
....:  temp = df.ix[:, ['FetchTime', 'MoistAve', 'MatTemp', 'TDRConduct', 'TDRAve', 'DeltaCount', 'tpAve', 'Moist%d' % d, 'TDR%d' % d]] 
....:  temp.columns = ['FetchTime', 'MoistAve', 'MatTemp', 'TDRConduct', 'TDRAve', 'DeltaCount', 'tpAve', 'RawMoist', 'RawTDR'] 
....:  temp['MeasureNo'] = d 
....:  data.append(temp) 
....:  
In [56]: test = pd.concat(data, ignore_index=True) 
In [62]: test.head() 
Out[62]: 
      FetchTime MoistAve MatTemp TDRConduct TDRAve DeltaCount tpAve RawMoist RawTDR MeasureNo 
0 2012-11-07 11:38:17  11.37  48.2  5.15 88.87   15 344.50  11.84  89   1 
1 2012-11-07 11:38:18  11.44  48.2  5.13 88.88   2 346.22  12.08  89   1 
2 2012-11-07 11:38:19  11.10  48.2  4.96 89.00   3 337.84  11.83  89   1 
3 2012-11-07 11:38:19  11.82  48.2  5.54 88.60   3 355.92  11.10  89   1 
4 2012-11-07 11:38:20  12.61  48.2  5.87 88.38   3 375.72  12.80  89   1 

Nhưng tôi không thấy một cách để ảnh hưởng đến nối để có được thứ tự tôi cần ... Có một cách khác để có được những kết quả DataFrame tôi cần?

+0

Bạn có thể tải 2 khung dữ liệu riêng biệt và tham gia/nhóm vào ngày giờ? – reptilicus

+0

Xem thêm http://stackoverflow.com/questions/11795992/pandas-efficiently-splitting-entries –

Trả lời

0

Điều này cho phép tất cả các cung cấp cho hàng thứ tư trong thử nghiệm bắt đầu từ 'i':

test.ix[i::4] 

Sử dụng vòng lặp cơ bản tương tự như trên, chỉ cần nối thêm các thiết lập của tất cả các ra hàng bắt đầu từ 0-3 sau khi bạn chạy của bạn mã trên.

data = []  
for i in range(0,3:):  
    temp = test.ix[i::4] 
    data.append(temp) 
test2 = pd.concat(data,ignore_index=True) 

Cập nhật: Tôi nhận ra bây giờ mà những gì bạn muốn không phải là mỗi hàng thứ tư nhưng mỗi hàng tháng, vì vậy đây sẽ chỉ được những gợi ý lặp trên. Lấy làm tiếc.

Cập nhật 2: Có thể không. Chúng tôi có thể tận dụng lợi thế của thực tế là mặc dù nối không trả lại thứ tự bạn muốn những gì nó trở lại có một bản đồ cố định cho những gì bạn muốn. d là số hàng trên mỗi dấu thời gian và m là số dấu thời gian.

Bạn dường như muốn các hàng từ thử nghiệm như sau: [0, m, 2m, 3m, 1, m + 1,2m + 1,3m + 1,2, m + 2,2m + 2,3m +2, ..., m-1,2m-1,3m-1,4m-1]

Tôi chắc chắn có nhiều cách đẹp hơn để tạo danh sách các chỉ mục đó, nhưng điều này làm việc cho tôi

d = 4 
m = 10 
small = (np.arange(0,m).reshape(m,1).repeat(d,1).T.reshape(-1,1)) 
shifter = (np.arange(0,d).repeat(m).reshape(-1,1).T * m) 
NewIndex = (shifter.reshape(d,-1) + small.reshape(d,-1)).T.reshape(-1,1) 
NewIndex = NewIndex.reshape(-1) 
test = test.ix[NewIndex] 
+0

Có một cách tiếp cận khác liên quan đến pd.stack và pd.merge có thể hoạt động. Nó phụ thuộc vào các trường thời gian. Khi tôi thấy các trường trong dữ liệu của bạn, các hàng 3 và 4 có cùng thời gian và dấu ngày. Đây có phải là sản phẩm của định dạng hoặc độ chính xác của dữ liệu được ghi lại hay không. Tôi hỏi vì khi bạn hiển thị đầu ra: – BKay

+0

Nếu nó chỉ là định dạng và thời gian được ghi lại với độ chính xác mà tất cả các mục là duy nhất, sau đó ngăn xếp và hợp nhất làm đi. Hãy cho tôi biết và tôi sẽ đăng một số mã. – BKay

1

Đây là giải pháp dựa trên việc lập chỉ mục mảng và lặp lại của numpy để tạo các giá trị được xếp chồng lên nhau và kết hợp của gấu trúc để xuất kết quả được ghép nối.

Trước tiên, tải mẫu dữ liệu của bạn vào một DataFrame (các đối số của read_csv được thay đổi một chút).

from cStringIO import StringIO 

data = """; No Time Date MoistAve MatTemp TDRConduct TDRAve DeltaCount tpAve Moist1 Moist2 Moist3 Moist4 TDR1 TDR2 TDR3 TDR4 
1 11:38:17 11.07.2012 11.37 48.20 5.15 88.87 15 344.50 11.84 11.35 11.59 15.25 89.0 89.0 89.0 88.0 
2 11:38:18 11.07.2012 11.44 48.20 5.13 88.88 2 346.22 12.08 11.83 -1.00 -1.00 89.0 89.0 -1.0 -1.0 
3 11:38:19 11.07.2012 11.10 48.20 4.96 89.00 3 337.84 11.83 11.59 10.62 -1.00 89.0 89.0 89.0 -1.0 
4 11:38:19 11.07.2012 11.82 48.20 5.54 88.60 3 355.92 11.10 13.54 12.32 -1.00 89.0 88.0 88.0 -1.0 
""" 

date_spec = {'FetchTime': [1, 2]} 
df = pd.read_csv(StringIO(data), header=0, sep='\s\s+',parse_dates=date_spec, na_values=['-1.0', '-1.00']) 

Sau đó xây dựng một vector de-chồng của TDRs và hợp nhất nó với các khung dữ liệu gốc

stacked_col_names = ['TDR1','TDR2','TDR3','TDR4'] 

repeated_row_indexes = np.repeat(np.arange(df.shape[0]),4) 
repeated_col_indexes = [np.where(df.columns == c)[0][0] for c in stacked_col_names] 

destacked_tdrs = pd.DataFrame(data=df.values[repeated_row_indexes,repeated_col_indexes],index=df.index[repeated_row_indexes],columns=['TDR']) 

ouput = pd.merge(left_index = True, right_index = True, left = df, right = destacked_tdrs) 

Với đầu ra mong muốn:

output.ix[:,['TDR1','TDR2','TDR3','TDR4','TDR']] 

    TDR1 TDR2 TDR3 TDR4 TDR 
0 89 89 89 88 89 
0 89 89 89 88 89 
0 89 89 89 88 89 
0 89 89 89 88 88 
1 89 89 NaN NaN 89 
1 89 89 NaN NaN 89 
1 89 89 NaN NaN NaN 
1 89 89 NaN NaN NaN 
2 89 89 89 NaN 89 
2 89 89 89 NaN 89 
2 89 89 89 NaN 89 
2 89 89 89 NaN NaN 
3 89 88 88 NaN 89 
3 89 88 88 NaN 88 
3 89 88 88 NaN 88 
3 89 88 88 NaN NaN 
Các vấn đề liên quan