2017-08-11 22 views
5

Hãy xem xét những điều sau hdfstore và dataframes dfdf2Tôi có thể cập nhật HDFStore không?

import pandas as pd 

store = pd.HDFStore('test.h5') 

midx = pd.MultiIndex.from_product([range(2), list('XYZ')], names=list('AB')) 
df = pd.DataFrame(dict(C=range(6)), midx) 

df 

    C 
A B 
0 X 0 
    Y 1 
    Z 2 
1 X 3 
    Y 4 
    Z 5 

midx2 = pd.MultiIndex.from_product([range(2), list('VWX')], names=list('AB')) 
df2 = pd.DataFrame(dict(C=range(6)), midx2) 

df2 

    C 
A B 
0 V 0 
    W 1 
    X 2 
1 V 3 
    W 4 
    X 5 

Tôi muốn đầu tiên viết df đến cửa hàng.

store.append('df', df) 

store.get('df') 

    C 
A B 
0 X 0 
    Y 1 
    Z 2 
1 X 3 
    Y 4 
    Z 5 

Tại một điểm sau đó trong thời gian tôi sẽ có một dataframe mà tôi muốn để cập nhật các cửa hàng với. Tôi muốn ghi đè lên các hàng có cùng giá trị chỉ mục như trong dataframe mới của tôi trong khi vẫn giữ nguyên các giá trị cũ.

Khi tôi làm

store.append('df', df2) 

store.get('df') 

    C 
A B 
0 X 0 
    Y 1 
    Z 2 
1 X 3 
    Y 4 
    Z 5 
0 V 0 
    W 1 
    X 2 
1 V 3 
    W 4 
    X 5 

Đây không phải là ở tất cả những gì tôi muốn. Lưu ý rằng (0, 'X')(1, 'X') được lặp lại. Tôi có thể thao tác dataframe kết hợp và ghi đè lên, nhưng tôi hy vọng sẽ làm việc với rất nhiều dữ liệu mà điều này sẽ không khả thi.

Làm cách nào để cập nhật cửa hàng để nhận?

 C 
A B 
0 V 0 
    W 1 
    X 2 
    Y 1 
    Z 2 
1 V 3 
    W 4 
    X 5 
    Y 4 
    Z 5 

Bạn sẽ thấy rằng Đối với mỗi mức độ 'A', 'Y' và 'Z' đều giống nhau, 'V''W' là người mới, và 'X' được cập nhật.

Cách chính xác để thực hiện việc này là gì?

+0

có thể giúp bạn làm việc với các chỉ số bình thường (không phải multiindex)? – MaxU

+0

Có ... dữ liệu thực của tôi có multiindex, nhưng nếu bạn thể hiện điều gì đó với chỉ mục duy nhất, tôi hài lòng với điều đó. – piRSquared

+0

OK, tôi cần một chút thời gian để chuẩn bị bản trình diễn ... – MaxU

Trả lời

3

Ý tưởng: xóa các hàng phù hợp (có giá trị chỉ mục phù hợp) khỏi HDF trước và sau đó nối thêm df2 vào HDFStore.

Sự cố: Tôi không thể tìm thấy cách sử dụng where="index in df2.index" cho chỉ mục nhiều chỉ mục.

Giải pháp: multiindexes chuyển đổi đầu tiên cho những người bình thường:

df.index = df.index.get_level_values(0).astype(str) + '_' + df.index.get_level_values(1).astype(str) 

df2.index = df2.index.get_level_values(0).astype(str) + '_' + df2.index.get_level_values(1).astype(str) 

sản lượng này:

In [348]: df 
Out[348]: 
    C 
0_X 0 
0_Y 1 
0_Z 2 
1_X 3 
1_Y 4 
1_Z 5 

In [349]: df2 
Out[349]: 
    C 
0_V 0 
0_W 1 
0_X 2 
1_V 3 
1_W 4 
1_X 5 

hãy chắc chắn rằng bạn sử dụng format='t'data_columns=True (index điều này sẽ tiết kiệm chỉ số và chỉ số tất cả các cột trong tệp HDF5, cho phép chúng tôi sử dụng chúng trong mệnh đề where) khi bạn tạo/nối các tệp HDF5:

store = pd.HDFStore('d:/temp/test1.h5') 
store.append('df', df, format='t', data_columns=True) 
store.close() 

bây giờ chúng tôi đầu tiên có thể loại bỏ những hàng từ HDFStore với chỉ số phù hợp:

store = pd.HDFStore('d:/temp/test1.h5') 

In [345]: store.remove('df', where="index in df2.index") 
Out[345]: 2 

và thêm df2:

In [346]: store.append('df', df2, format='t', data_columns=True, append=True) 

Kết quả:

In [347]: store.get('df') 
Out[347]: 
    C 
0_Y 1 
0_Z 2 
1_Y 4 
1_Z 5 
0_V 0 
0_W 1 
0_X 2 
1_V 3 
1_W 4 
1_X 5 
+1

Cảm ơn bạn rất nhiều! Tôi đã học được rất nhiều ở đó. Tôi đã có một số ý tưởng ngay bây giờ. Tôi sẽ báo cáo lại. – piRSquared

+0

@piRSquared, vui mừng nếu nó giúp. Có, vui lòng cung cấp phản hồi ngắn về giải pháp cuối cùng của bạn. Điều này cũng sẽ giúp những người có cùng một vấn đề ... – MaxU

+0

Có một vấn đề với cú pháp 'where =" index trong df.index "'. Xem Pandas [bug # 17567] (https://github.com/pandas-dev/pandas/issues/17567) để được giải thích và giải quyết. –

Các vấn đề liên quan