2015-02-10 28 views
8

Tôi đang cố gắng hiểu pandasMultiIndexDataFrame và cách gán dữ liệu cho chúng. Cụ thể là tôi quan tâm đến việc chỉ định toàn bộ các khối khớp với một khung dữ liệu nhỏ hơn.chuyển nhượng multiand của gấu trúc từ một khung dữ liệu khác

ix = pd.MultiIndex.from_product([['A', 'B'], ['a', 'b', 'c', 'd']]) 
df = pd.DataFrame(index=ix, columns=['1st', '2nd', '3rd'], dtype=np.float64) 
df_ = pd.DataFrame(index=['a', 'b', 'c', 'd'], columns=['1st', '2nd', '3rd'], data=np.random.rand(4, 3)) 
df_ 

    1st  2nd  3rd 
a 0.730251 0.468134 0.876926 
b 0.104990 0.082461 0.129083 
c 0.993608 0.117799 0.341811 
d 0.784950 0.840145 0.016777 

df là như nhau ngoại trừ việc tất cả các giá trị là NaN và có hai khối AB. Bây giờ nếu tôi muốn gán các giá trị từ df_ để df tôi sẽ tưởng tượng tôi có thể làm một cái gì đó giống như

df.loc['A',:] = df_    # Runs, does not work 
df.loc[('A','a'):('A','d')] = df_ # AssertionError (??) 'Start slice bound is non-scalar' 
df.loc[('A','a'):('A','d')]  # No AssertionError (??) 

idx = pd.IndexSlice 
df.loc[idx['A', :]] = df_   # Runs, does not work 

Không ai trong số những công việc, họ lại tất cả các giá trị trong df như NaN, mặc dù df.loc[idx['A', :]] mang lại cho tôi một lát của khung dữ liệu khớp chính xác với khung phụ (df_). Vậy đây có phải là trường hợp đặt giá trị trên một chế độ xem không? Một cách rõ ràng iterating trên các chỉ mục trong công trình df_

# this is fine 
for v in df_.index: 
    df.loc[idx['A', v]] = df_.loc[v] 

# this is also fine 
for v in df_.index: 
    df.loc['A', v] = df_.loc[v] 

Có thậm chí có thể gán toàn bộ khối như thế này (loại giống như NumPy)? Nếu không, đó là tốt, tôi chỉ đơn giản là cố gắng để hiểu làm thế nào hệ thống hoạt động.

Có một câu hỏi liên quan đến slicer chỉ mục, nhưng đó là về việc gán một giá trị duy nhất cho một phần được che giấu của DataFrame, chứ không phải về việc gán khối. Pandas : Proper way to set values based on condition for subset of multiindex dataframe

Trả lời

12

Khi bạn sử dụng

df.loc['A', :] = df_ 

Pandas cố gắng để sắp xếp các chỉ số của df_ với chỉ số của một sub-DataFrame của df. Tuy nhiên, tại số point in the code nơi căn chỉnh được thực hiện, khung dữ liệu phụ có MultiIndex, không phải chỉ mục duy nhất mà bạn xem là kết quả của df.loc['A', :].

Do đó căn chỉnh không thành công vì df_ có một chỉ mục duy nhất, không phải là MultiIndex mà là cần thiết. Để thấy rằng chỉ số của df_ thực sự là vấn đề, lưu ý rằng

ix_ = pd.MultiIndex.from_product([['A'], ['a', 'b', 'c', 'd']]) 
df_.index = ix_ 
df.loc['A', :] = df_ 
print(df) 

thành công, năng suất giống như

A a 0.229970 0.730824 0.784356 
    b 0.584390 0.628337 0.318222 
    c 0.257192 0.624273 0.221279 
    d 0.787023 0.056342 0.240735 
B a  NaN  NaN  NaN 
    b  NaN  NaN  NaN 
    c  NaN  NaN  NaN 
    d  NaN  NaN  NaN 

Tất nhiên, có thể bạn không muốn phải tạo một MultiIndex mới mỗi thời gian bạn muốn chỉ định một khối giá trị.Vì vậy, thay vào đó, để làm việc xung quanh vấn đề sự liên kết này, bạn có thể sử dụng một mảng NumPy như giá trị chuyển nhượng:

df.loc['A', :] = df_.values 

Kể từ df_.values là một mảng NumPy và một mảng không có chỉ mục, no alignment is performed và sự phân công mang lại cùng kết quả như trên. Thủ thuật này khi sử dụng một mảng NumPy khi bạn không muốn căn chỉnh các chỉ mục áp dụng cho nhiều tình huống khi sử dụng Pandas.

Cũng lưu ý rằng phân-by-NumPy mảng cũng có thể giúp bạn thực hiện nhiệm vụ phức tạp hơn như các hàng mà không tiếp giáp:

idx = pd.IndexSlice 
df.loc[idx[:,('a','b')], :] = df_.values 

mang

In [85]: df 
Out[85]: 
      1st  2nd  3rd 
A a 0.229970 0.730824 0.784356 
    b 0.584390 0.628337 0.318222 
    c  NaN  NaN  NaN 
    d  NaN  NaN  NaN 
B a 0.257192 0.624273 0.221279 
    b 0.787023 0.056342 0.240735 
    c  NaN  NaN  NaN 
    d  NaN  NaN  NaN 

ví dụ.

+0

Tôi thấy đó là một lời giải thích tốt, cảm ơn. Tôi thích 'df_.values', đặc biệt là vì nó cho phép bạn làm tất cả các loại bài tập một phần điên rồ. Chỉ cần cẩn thận để lập chỉ mục các khung dữ liệu theo cùng một thứ tự, tôi đã tự hỏi tại sao một số dữ liệu của tôi đột nhiên lật xung quanh (oops). –

+0

Nếu thứ tự của các giá trị khác nhau thì có thể dễ dàng nhất để tạo chỉ mục 'df_' thành một MultiIndex và cho phép Pandas xử lý sự liên kết cho bạn. – unutbu

+0

Thứ tự khác vì tôi đã ngu ngốc, nhưng tôi sẽ ghi nhớ điều đó. –

0

Tôi đã làm 8480 một thời gian trở lại, giúp phân bổ khung phụ với các cột hoạt động. như vậy, bạn có thể làm như sau như một công việc xung quanh:

>>> rf 
    1st 2nd 3rd 
a 0.730 0.468 0.877 
b 0.105 0.082 0.129 
c 0.994 0.118 0.342 
d 0.785 0.840 0.017 
>>> df.T['A'] = rf.T # take transpose of both sides 
>>> df 
     1st 2nd 3rd 
A a 0.730 0.468 0.877 
    b 0.105 0.082 0.129 
    c 0.994 0.118 0.342 
    d 0.785 0.840 0.017 
B a NaN NaN NaN 
    b NaN NaN NaN 
    c NaN NaN NaN 
    d NaN NaN NaN 

những gì đã nói, bạn có thể muốn đăng bài này như một lỗi trên github.

chỉnh sửa: Dường như thêm một lát giả ở cuối cũng làm việc:

>>> df.loc['A'][:] = rf 
>>> df 
     1st 2nd 3rd 
A a 0.730 0.468 0.877 
    b 0.105 0.082 0.129 
    c 0.994 0.118 0.342 
    d 0.785 0.840 0.017 
B a NaN NaN NaN 
    b NaN NaN NaN 
    c NaN NaN NaN 
    d NaN NaN NaN 
+0

không chỉ mục giả ở cuối tạo một 'khung nhìn' của khung dữ liệu như được ghi lại [ở đây] (http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view -versus-copy) - Ít nhất tôi cũng nhận được cảnh báo về việc gán giá trị cho một khung nhìn –

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