Làm thế nào để làm cho các ví dụ gấu trúc tái sản xuất tốt


221

Đã dành một khoảng thời gian kha khá để xem cả các thẻ trên SO, ấn tượng mà tôi nhận được là các pandascâu hỏi ít có khả năng chứa dữ liệu có thể lặp lại. Đây là điều mà cộng đồng R đã khá khuyến khích và nhờ những người hướng dẫn như thế này , những người mới đến có thể nhận được sự giúp đỡ trong việc đưa ra những ví dụ này. Những người có thể đọc các hướng dẫn này và quay lại với dữ liệu có thể tái tạo thường sẽ có nhiều may mắn hơn khi nhận được câu trả lời cho câu hỏi của họ.

Làm thế nào chúng ta có thể tạo ra các ví dụ tái sản xuất tốt cho các pandascâu hỏi? Các datafram đơn giản có thể được đặt cùng nhau, ví dụ:

import pandas as pd
df = pd.DataFrame({'user': ['Bob', 'Jane', 'Alice'], 
                   'income': [40000, 50000, 42000]})

Nhưng nhiều bộ dữ liệu mẫu cần cấu trúc phức tạp hơn, ví dụ:

  • datetime chỉ số hoặc dữ liệu
  • Nhiều biến phân loại (có tương đương với expand.grid()hàm R , tạo ra tất cả các kết hợp có thể có của một số biến đã cho không?)
  • Dữ liệu Multi Index hoặc Bảng điều khiển

Đối với các bộ dữ liệu khó giả lập bằng cách sử dụng một vài dòng mã, có tương đương với R dput()cho phép bạn tạo mã có thể sao chép để tạo lại cơ sở hạ tầng của mình không?


8
Nếu bạn sao chép đầu ra của in, hầu hết người trả lời có thể sử dụng read_clipboard () ... ngoại trừ Multi Index: s. Nói rằng, dict là bổ sung tốt
Andy Hayden

8
Ngoài những gì Andy nói, tôi nghĩ rằng dán sao chép df.head(N).to_dict(), Nmột số hợp lý là một cách tốt để đi. Phần thưởng + 1 cho việc thêm các ngắt dòng đẹp vào đầu ra. Đối với dấu thời gian, thông thường bạn sẽ chỉ cần thêm from pandas import Timestampvào đầu mã.
Paul H

Câu trả lời:


323

Lưu ý: Các ý tưởng ở đây khá chung chung cho Stack Overflow, thực sự là các câu hỏi .

Tuyên bố từ chối trách nhiệm: Viết một câu hỏi hay là CỨNG.

Tốt:

  • bao gồm DataFrame nhỏ *, dưới dạng mã có thể chạy được:

    In [1]: df = pd.DataFrame([[1, 2], [1, 3], [4, 6]], columns=['A', 'B'])

    hoặc làm cho nó "sao chép và dán" bằng cách sử dụng pd.read_clipboard(sep='\s\s+'), bạn có thể định dạng văn bản cho phần tô sáng Stack Overflow và sử dụng Ctrl+ K(hoặc thêm bốn khoảng trắng cho mỗi dòng) hoặc đặt ba dấu ở trên và bên dưới mã của bạn với mã của bạn mà không bị ràng buộc:

    In [2]: df
    Out[2]: 
       A  B
    0  1  2
    1  1  3
    2  4  6

    pd.read_clipboard(sep='\s\s+')tự kiểm tra

    * Tôi thực sự có nghĩa là nhỏ , phần lớn các ví dụ DataFrames có thể cần ít hơn 6 hàng trích dẫntôi cá là tôi có thể làm điều đó trong 5 hàng. Bạn có thể tái tạo lỗi với df = df.head(), nếu không phải loay hoay để xem liệu bạn có thể tạo ra một DataFrame nhỏ thể hiện vấn đề mà bạn đang gặp phải không.

    * Mọi quy tắc đều có ngoại lệ, quy tắc rõ ràng là về các vấn đề về hiệu suất ( trong trường hợp đó chắc chắn sử dụng% timeit và có thể là% prun ), nơi bạn nên tạo (xem xét sử dụng np.random.seed để chúng tôi có cùng một khung chính xác) : df = pd.DataFrame(np.random.randn(100000000, 10)). Nói rằng, "làm cho mã này nhanh cho tôi" không hoàn toàn theo chủ đề cho trang web ...

  • viết ra kết quả mà bạn mong muốn (tương tự như trên)

    In [3]: iwantthis
    Out[3]: 
       A  B
    0  1  5
    1  4  6

    Giải thích những con số đến từ đâu: 5 là tổng của cột B cho các hàng trong đó A là 1.

  • hiển thị bạn đã thử:

    In [4]: df.groupby('A').sum()
    Out[4]: 
       B
    A   
    1  5
    4  6

    Nhưng nói những gì không chính xác: cột A nằm trong chỉ mục chứ không phải là một cột.

  • hãy cho thấy bạn đã thực hiện một số nghiên cứu ( tìm kiếm tài liệu , tìm kiếm StackOverflow ), tóm tắt:

    Chuỗi doc cho tổng chỉ đơn giản là "Tính tổng các giá trị nhóm"

    Các tài liệu nhóm không đưa ra bất kỳ ví dụ cho điều này.

    Ngoài ra: câu trả lời ở đây là sử dụng df.groupby('A', as_index=False).sum().

  • nếu có liên quan rằng bạn có các cột Dấu thời gian, ví dụ: bạn đang lấy mẫu lại hoặc một cái gì đó, thì hãy rõ ràng và áp dụng pd.to_datetimechúng cho các biện pháp tốt **.

    df['date'] = pd.to_datetime(df['date']) # this column ought to be date..

    ** Đôi khi đây là vấn đề của chính nó: chúng là các chuỗi.

Những người xấu:

  • không bao gồm Multi Index mà chúng tôi không thể sao chép và dán (xem bên trên), đây là một sự bất bình với màn hình mặc định của gấu trúc nhưng dù sao cũng gây khó chịu:

    In [11]: df
    Out[11]:
         C
    A B   
    1 2  3
      2  6

    Cách chính xác là bao gồm một DataFrame thông thường với một set_indexcuộc gọi:

    In [12]: df = pd.DataFrame([[1, 2, 3], [1, 2, 6]], columns=['A', 'B', 'C']).set_index(['A', 'B'])
    
    In [13]: df
    Out[13]: 
         C
    A B   
    1 2  3
      2  6
  • cung cấp cái nhìn sâu sắc về những gì nó là khi đưa ra kết quả bạn muốn:

       B
    A   
    1  1
    5  0

    Hãy cụ thể về cách bạn có các số (chúng là gì) ... kiểm tra kỹ xem chúng có đúng không.

  • Nếu mã của bạn gây ra lỗi, hãy bao gồm toàn bộ dấu vết ngăn xếp (điều này có thể được chỉnh sửa sau nếu quá ồn). Hiển thị số dòng (và dòng tương ứng của mã của bạn đang tăng so với).

Xấu xí:

  • không liên kết đến một csv mà chúng tôi không có quyền truy cập (lý tưởng nhất là không liên kết với một nguồn bên ngoài nào cả ...)

    df = pd.read_csv('my_secret_file.csv')  # ideally with lots of parsing options

    Hầu hết dữ liệu là độc quyền, chúng tôi nhận được rằng: Tạo dữ liệu tương tự và xem liệu bạn có thể tái tạo vấn đề (một cái gì đó nhỏ).

  • không giải thích tình huống một cách mơ hồ bằng các từ, như bạn có một DataFrame "lớn", hãy đề cập đến một số tên cột đi qua (hãy chắc chắn không đề cập đến các dtypes của chúng). Hãy thử và đi vào nhiều chi tiết về một cái gì đó hoàn toàn vô nghĩa mà không nhìn thấy bối cảnh thực tế. Có lẽ không ai thậm chí sẽ đọc đến cuối đoạn này.

    Bài luận là xấu, nó dễ dàng hơn với các ví dụ nhỏ.

  • không bao gồm hơn 10 dòng (100+ ??) dữ liệu được trộn trước khi đến câu hỏi thực tế của bạn.

    Xin vui lòng, chúng tôi thấy đủ điều này trong công việc hàng ngày của chúng tôi. Chúng tôi muốn giúp đỡ, nhưng không như thế này ... .
    Cắt phần giới thiệu và chỉ hiển thị các DataFrames có liên quan (hoặc các phiên bản nhỏ của chúng) trong bước gây rắc rối cho bạn.

Dù sao, hãy vui vẻ học Python, NumPy và Pandas!


30
+1 cho tiền pd.read_clipboard(sep='\s\s+')boa. Khi tôi đăng các câu hỏi SO cần một khung dữ liệu đặc biệt nhưng dễ chia sẻ, như câu hỏi này tôi xây dựng nó trong excel, sao chép nó vào khay nhớ tạm của tôi, sau đó hướng dẫn các SOers làm tương tự. Tiết kiệm rất nhiều thời gian!
zelusp

1
các pd.read_clipboard(sep='\s\s+')gợi ý dường như không làm việc nếu bạn đang sử dụng Python trên một máy chủ từ xa, đó là nơi rất nhiều bộ dữ liệu lớn sống.
dùng5359531

1
Tại sao pd.read_clipboard(sep='\s\s+'), và không đơn giản hơn pd.read_clipboard()(với mặc định ‘s+’)? Nhu cầu đầu tiên cần ít nhất 2 ký tự khoảng trắng, có thể gây ra sự cố nếu chỉ có 1 (ví dụ: xem trong câu trả lời của @JohnE ).
MarianD

3
@MarianD lý do mà \ s \ s + rất phổ biến là thường có một ví dụ như trong một tên cột, nhưng nhiều thì hiếm hơn và đầu ra gấu trúc đặt ít nhất hai giữa hai cột. Vì đây chỉ dành cho đồ chơi / bộ dữ liệu nhỏ nên nó khá mạnh / phần lớn các trường hợp. Lưu ý: các tab được phân tách sẽ là một câu chuyện khác nhau, mặc dù stackoverflow thay thế các tab bằng dấu cách, nhưng nếu bạn có tsv thì chỉ cần sử dụng \ t.
Andy Hayden

3
Ugh, tôi luôn sử dụng pd.read_clipboard(), khi chúng là khoảng trắng, tôi làm pd.read_clipboard(sep='\s+{2,}', engine='python'):: P
U10-Forward

72

Cách tạo bộ dữ liệu mẫu

Điều này chủ yếu là để mở rộng câu trả lời của @ AndyHayden bằng cách cung cấp các ví dụ về cách bạn có thể tạo các tệp dữ liệu mẫu. Pandas và (đặc biệt) numpy cung cấp cho bạn nhiều công cụ cho việc này để bạn thường có thể tạo một bản fax hợp lý của bất kỳ tập dữ liệu thực nào chỉ bằng một vài dòng mã.

Sau khi nhập numpy và gấu trúc, hãy đảm bảo cung cấp một hạt giống ngẫu nhiên nếu bạn muốn mọi người có thể sao chép chính xác dữ liệu và kết quả của bạn.

import numpy as np
import pandas as pd

np.random.seed(123)

Một ví dụ bồn rửa nhà bếp

Đây là một ví dụ cho thấy một loạt những điều bạn có thể làm. Tất cả các loại dữ liệu mẫu hữu ích có thể được tạo từ một tập hợp con của điều này:

df = pd.DataFrame({ 

    # some ways to create random data
    'a':np.random.randn(6),
    'b':np.random.choice( [5,7,np.nan], 6),
    'c':np.random.choice( ['panda','python','shark'], 6),

    # some ways to create systematic groups for indexing or groupby
    # this is similar to r's expand.grid(), see note 2 below
    'd':np.repeat( range(3), 2 ),
    'e':np.tile(   range(2), 3 ),

    # a date range and set of random dates
    'f':pd.date_range('1/1/2011', periods=6, freq='D'),
    'g':np.random.choice( pd.date_range('1/1/2011', periods=365, 
                          freq='D'), 6, replace=False) 
    })

Điều này tạo ra:

          a   b       c  d  e          f          g
0 -1.085631 NaN   panda  0  0 2011-01-01 2011-08-12
1  0.997345   7   shark  0  1 2011-01-02 2011-11-10
2  0.282978   5   panda  1  0 2011-01-03 2011-10-30
3 -1.506295   7  python  1  1 2011-01-04 2011-09-07
4 -0.578600 NaN   shark  2  0 2011-01-05 2011-02-27
5  1.651437   7  python  2  1 2011-01-06 2011-02-03

Một số lưu ý:

  1. np.repeatnp.tile(cột de) rất hữu ích để tạo các nhóm và chỉ mục một cách rất thường xuyên. Đối với 2 cột, điều này có thể được sử dụng để dễ dàng nhân đôi r expand.grid()nhưng cũng linh hoạt hơn trong khả năng cung cấp một tập hợp con của tất cả các hoán vị. Tuy nhiên, đối với 3 cột trở lên, cú pháp nhanh chóng trở nên khó sử dụng.
  2. Để thay thế trực tiếp hơn cho r, expand.grid()hãy xem itertoolsgiải pháp trong sách dạy nấu ăn của gấu trúc hoặc np.meshgridgiải pháp được hiển thị ở đây . Những người sẽ cho phép bất kỳ số lượng kích thước.
  3. Bạn có thể làm một chút với np.random.choice. Ví dụ: trong cột g, chúng tôi có lựa chọn ngẫu nhiên 6 ngày kể từ năm 2011. Ngoài ra, bằng cách cài đặt, replace=Falsechúng tôi có thể đảm bảo những ngày này là duy nhất - rất tiện dụng nếu chúng tôi muốn sử dụng chỉ mục này làm chỉ mục với các giá trị duy nhất.

Dữ liệu thị trường chứng khoán giả

Ngoài việc lấy các tập hợp con của mã trên, bạn có thể kết hợp thêm các kỹ thuật để làm bất cứ điều gì. Ví dụ: đây là một ví dụ ngắn kết hợp np.tiledate_rangetạo dữ liệu đánh dấu mẫu cho 4 cổ phiếu có cùng ngày:

stocks = pd.DataFrame({ 
    'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
    'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
    'price':(np.random.randn(100).cumsum() + 10) })

Bây giờ chúng tôi có một bộ dữ liệu mẫu với 100 dòng (25 ngày trên mỗi mã), nhưng chúng tôi chỉ sử dụng 4 dòng để làm điều đó, giúp mọi người khác dễ dàng sao chép mà không cần sao chép và dán 100 dòng mã. Sau đó, bạn có thể hiển thị các tập hợp con của dữ liệu nếu nó giúp giải thích câu hỏi của bạn:

>>> stocks.head(5)

        date      price ticker
0 2011-01-01   9.497412   aapl
1 2011-01-02  10.261908   aapl
2 2011-01-03   9.438538   aapl
3 2011-01-04   9.515958   aapl
4 2011-01-05   7.554070   aapl

>>> stocks.groupby('ticker').head(2)

         date      price ticker
0  2011-01-01   9.497412   aapl
1  2011-01-02  10.261908   aapl
25 2011-01-01   8.277772   goog
26 2011-01-02   7.714916   goog
50 2011-01-01   5.613023   yhoo
51 2011-01-02   6.397686   yhoo
75 2011-01-01  11.736584   msft
76 2011-01-02  11.944519   msft

2
Câu trả lời chính xác. Sau khi viết câu hỏi này, tôi thực sự đã viết một bài thực hiện rất ngắn, đơn giản expand.grid()bao gồm trong sách dạy nấu ăn của gấu trúc , bạn cũng có thể đưa nó vào câu trả lời của mình. Câu trả lời của bạn cho thấy cách tạo bộ dữ liệu phức tạp hơn expand_grid()chức năng của tôi có thể xử lý, điều này thật tuyệt.
Marius

46

Nhật ký của người trả lời

Lời khuyên tốt nhất của tôi khi đặt câu hỏi sẽ là chơi theo tâm lý của những người trả lời câu hỏi. Là một trong những người đó, tôi có thể hiểu rõ lý do tại sao tôi trả lời một số câu hỏi nhất định và tại sao tôi không trả lời những người khác.

Động lực

Tôi có động lực để trả lời các câu hỏi vì nhiều lý do

  1. Stackoverflow.com là một nguồn tài nguyên vô cùng quý giá đối với tôi. Tôi muốn trả lại.
  2. Trong nỗ lực trả lại, tôi đã thấy trang web này là một tài nguyên thậm chí còn mạnh hơn trước đây. Trả lời câu hỏi là một kinh nghiệm học tập cho tôi và tôi thích học hỏi. Đọc câu trả lời này và nhận xét từ bác sĩ thú y khác . Loại tương tác này làm cho tôi hạnh phúc.
  3. Tôi thích điểm!
  4. Xem # 3.
  5. Tôi thích những vấn đề thú vị.

Tất cả các ý định thuần túy nhất của tôi đều tuyệt vời và tất cả, nhưng tôi có được sự hài lòng đó nếu tôi trả lời 1 câu hỏi hoặc 30. Điều gì thúc đẩy sự lựa chọn của tôi cho câu hỏi nào trả lời có một thành phần lớn của tối đa hóa điểm.

Tôi cũng sẽ dành thời gian cho những vấn đề thú vị nhưng điều đó rất ít và không giúp được người hỏi cần giải pháp cho một câu hỏi không thú vị. Đặt cược tốt nhất của bạn để khiến tôi trả lời một câu hỏi là phục vụ câu hỏi đó trên một đĩa chín để tôi trả lời nó với ít nỗ lực nhất có thể. Nếu tôi đang xem hai câu hỏi và một câu hỏi có mã, tôi có thể sao chép dán để tạo tất cả các biến tôi cần ... Tôi đang lấy đó! Tôi sẽ quay lại với người khác nếu có thời gian.

Tư vấn chính

Làm cho nó dễ dàng cho những người trả lời câu hỏi.

  • Cung cấp mã tạo các biến cần thiết.
  • Giảm thiểu mã đó. Nếu mắt tôi trừng trừng khi tôi nhìn vào bài đăng, tôi sẽ chuyển sang câu hỏi tiếp theo hoặc quay lại với bất cứ điều gì khác mà tôi đang làm.
  • Hãy suy nghĩ về những gì bạn đang hỏi và được cụ thể. Chúng tôi muốn xem những gì bạn đã làm vì ngôn ngữ tự nhiên (tiếng Anh) không chính xác và khó hiểu. Các mẫu mã về những gì bạn đã thử giúp giải quyết sự không nhất quán trong mô tả ngôn ngữ tự nhiên.
  • Xin vui lòng cho thấy những gì bạn mong đợi !!! Tôi phải ngồi xuống và thử mọi thứ. Tôi gần như không bao giờ biết câu trả lời cho một câu hỏi mà không thử một số thứ. Nếu tôi không thấy một ví dụ về những gì bạn đang tìm kiếm, tôi có thể chuyển câu hỏi vì tôi không cảm thấy muốn đoán.

Danh tiếng của bạn không chỉ là danh tiếng của bạn.

Tôi thích điểm (tôi đã đề cập ở trên). Nhưng những điểm đó không thực sự là danh tiếng của tôi. Danh tiếng thực sự của tôi là sự hợp nhất của những gì người khác trên trang web nghĩ về tôi. Tôi cố gắng để công bằng và trung thực và tôi hy vọng những người khác có thể thấy điều đó. Điều đó có nghĩa là gì đối với người hỏi là, chúng ta nhớ những hành vi của người hỏi. Nếu bạn không chọn câu trả lời và đưa ra câu trả lời hay, tôi nhớ. Nếu bạn cư xử theo cách tôi không thích hoặc theo cách tôi thích, tôi nhớ. Điều này cũng đóng vai trò trong đó câu hỏi tôi sẽ trả lời.


Dù sao, tôi có thể tiếp tục, nhưng tôi sẽ tha cho tất cả các bạn thực sự đọc nó.


26

Thách thức Một trong những khía cạnh thách thức nhất của việc trả lời các câu hỏi SO là thời gian cần thiết để tạo lại vấn đề (bao gồm cả dữ liệu). Những câu hỏi không có cách rõ ràng để tái tạo dữ liệu ít có khả năng được trả lời. Cho rằng bạn đang dành thời gian để viết câu hỏi và bạn có một vấn đề mà bạn muốn trợ giúp, bạn có thể dễ dàng tự giúp mình bằng cách cung cấp dữ liệu mà người khác có thể sử dụng để giúp giải quyết vấn đề của bạn.

Các hướng dẫn được cung cấp bởi @Andy để viết các câu hỏi Pandas tốt là một nơi tuyệt vời để bắt đầu. Để biết thêm thông tin, hãy tham khảo cách hỏi và cách tạo các ví dụ Tối thiểu, Hoàn chỉnh và Có thể kiểm chứng .

Vui lòng nêu rõ câu hỏi của bạn trả trước. Sau khi dành thời gian để viết câu hỏi của bạn và bất kỳ mã mẫu nào, hãy thử đọc nó và cung cấp một 'Tóm tắt điều hành' cho người đọc của bạn để tóm tắt vấn đề và nêu rõ câu hỏi.

Câu hỏi gốc :

Tôi có dữ liệu này ...

Tôi muốn làm điều này...

Tôi muốn kết quả của mình giống như thế này ...

Tuy nhiên, khi tôi cố gắng thực hiện [điều này], tôi gặp vấn đề sau ...

Tôi đã cố gắng tìm giải pháp bằng cách thực hiện [điều này] và [điều đó].

Làm thế nào để tôi sửa chữa nó?

Tùy thuộc vào lượng dữ liệu, mã mẫu và ngăn xếp lỗi được cung cấp, người đọc cần phải đi một chặng đường dài trước khi hiểu vấn đề là gì. Hãy thử đặt lại câu hỏi của bạn để câu hỏi được đặt lên hàng đầu, sau đó cung cấp các chi tiết cần thiết.

Câu hỏi sửa đổi :

Hỏi: Làm thế nào tôi có thể làm [điều này]?

Tôi đã cố gắng tìm giải pháp bằng cách thực hiện [điều này] và [điều đó].

Khi tôi cố gắng thực hiện [điều này], tôi gặp vấn đề sau ...

Tôi muốn kết quả cuối cùng của mình giống như thế này ...

Đây là một số mã tối thiểu có thể tái tạo vấn đề của tôi ...

Và đây là cách tạo lại dữ liệu mẫu của tôi: df = pd.DataFrame({'A': [...], 'B': [...], ...})

CUNG CẤP DỮ LIỆU MẪU NẾU CẦN !!!

Đôi khi chỉ cần phần đầu hoặc phần đuôi của DataFrame là tất cả những gì cần thiết. Bạn cũng có thể sử dụng các phương pháp được đề xuất bởi @JohnE để tạo các bộ dữ liệu lớn hơn có thể được sao chép bởi những người khác. Sử dụng ví dụ của anh ấy để tạo DataFrame 100 hàng giá cổ phiếu:

stocks = pd.DataFrame({ 
    'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
    'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
    'price':(np.random.randn(100).cumsum() + 10) })

Nếu đây là dữ liệu thực tế của bạn, bạn có thể chỉ muốn bao gồm phần đầu và / hoặc phần đuôi của khung dữ liệu như sau (hãy chắc chắn ẩn danh bất kỳ dữ liệu nhạy cảm nào):

>>> stocks.head(5).to_dict()
{'date': {0: Timestamp('2011-01-01 00:00:00'),
  1: Timestamp('2011-01-01 00:00:00'),
  2: Timestamp('2011-01-01 00:00:00'),
  3: Timestamp('2011-01-01 00:00:00'),
  4: Timestamp('2011-01-02 00:00:00')},
 'price': {0: 10.284260107718254,
  1: 11.930300761831457,
  2: 10.93741046217319,
  3: 10.884574289565609,
  4: 11.78005850418319},
 'ticker': {0: 'aapl', 1: 'aapl', 2: 'aapl', 3: 'aapl', 4: 'aapl'}}

>>> pd.concat([stocks.head(), stocks.tail()], ignore_index=True).to_dict()
{'date': {0: Timestamp('2011-01-01 00:00:00'),
  1: Timestamp('2011-01-01 00:00:00'),
  2: Timestamp('2011-01-01 00:00:00'),
  3: Timestamp('2011-01-01 00:00:00'),
  4: Timestamp('2011-01-02 00:00:00'),
  5: Timestamp('2011-01-24 00:00:00'),
  6: Timestamp('2011-01-25 00:00:00'),
  7: Timestamp('2011-01-25 00:00:00'),
  8: Timestamp('2011-01-25 00:00:00'),
  9: Timestamp('2011-01-25 00:00:00')},
 'price': {0: 10.284260107718254,
  1: 11.930300761831457,
  2: 10.93741046217319,
  3: 10.884574289565609,
  4: 11.78005850418319,
  5: 10.017209045035006,
  6: 10.57090128181566,
  7: 11.442792747870204,
  8: 11.592953372130493,
  9: 12.864146419530938},
 'ticker': {0: 'aapl',
  1: 'aapl',
  2: 'aapl',
  3: 'aapl',
  4: 'aapl',
  5: 'msft',
  6: 'msft',
  7: 'msft',
  8: 'msft',
  9: 'msft'}}

Bạn cũng có thể muốn cung cấp một mô tả về DataFrame (chỉ sử dụng các cột có liên quan). Điều này giúp người khác dễ dàng kiểm tra các loại dữ liệu của từng cột và xác định các lỗi phổ biến khác (ví dụ: ngày như chuỗi so với datetime64 so với đối tượng):

stocks.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100 entries, 0 to 99
Data columns (total 3 columns):
date      100 non-null datetime64[ns]
price     100 non-null float64
ticker    100 non-null object
dtypes: datetime64[ns](1), float64(1), object(1)

LƯU Ý: Nếu DataFrame của bạn có Đa chỉ số:

Nếu DataFrame của bạn có multiindex, trước tiên bạn phải đặt lại trước khi gọi to_dict. Sau đó, bạn cần tạo lại chỉ mục bằng cách sử dụng set_index:

# MultiIndex example.  First create a MultiIndex DataFrame.
df = stocks.set_index(['date', 'ticker'])
>>> df
                       price
date       ticker           
2011-01-01 aapl    10.284260
           aapl    11.930301
           aapl    10.937410
           aapl    10.884574
2011-01-02 aapl    11.780059
...

# After resetting the index and passing the DataFrame to `to_dict`, make sure to use 
# `set_index` to restore the original MultiIndex.  This DataFrame can then be restored.

d = df.reset_index().to_dict()
df_new = pd.DataFrame(d).set_index(['date', 'ticker'])
>>> df_new.head()
                       price
date       ticker           
2011-01-01 aapl    10.284260
           aapl    11.930301
           aapl    10.937410
           aapl    10.884574
2011-01-02 aapl    11.780059

12

Đây là phiên bản của tôi dput- công cụ R tiêu chuẩn để tạo báo cáo có thể lặp lại - cho Pandas DataFrames. Nó có thể sẽ thất bại đối với các khung phức tạp hơn, nhưng dường như thực hiện công việc trong các trường hợp đơn giản:

import pandas as pd
def dput (x):
    if isinstance(x,pd.Series):
        return "pd.Series(%s,dtype='%s',index=pd.%s)" % (list(x),x.dtype,x.index)
    if isinstance(x,pd.DataFrame):
        return "pd.DataFrame({" + ", ".join([
            "'%s': %s" % (c,dput(x[c])) for c in x.columns]) + (
                "}, index=pd.%s)" % (x.index))
    raise NotImplementedError("dput",type(x),x)

hiện nay,

df = pd.DataFrame({'a':[1,2,3,4,2,1,3,1]})
assert df.equals(eval(dput(df)))
du = pd.get_dummies(df.a,"foo")
assert du.equals(eval(dput(du)))
di = df
di.index = list('abcdefgh')
assert di.equals(eval(dput(di)))

Lưu ý rằng điều này tạo ra một đầu ra dài dòng hơn nhiều DataFrame.to_dict, ví dụ,

pd.DataFrame({
  'foo_1':pd.Series([1, 0, 0, 0, 0, 1, 0, 1],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_2':pd.Series([0, 1, 0, 0, 1, 0, 0, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_3':pd.Series([0, 0, 1, 0, 0, 0, 1, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_4':pd.Series([0, 0, 0, 1, 0, 0, 0, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1))},
  index=pd.RangeIndex(start=0, stop=8, step=1))

đấu với

{'foo_1': {0: 1, 1: 0, 2: 0, 3: 0, 4: 0, 5: 1, 6: 0, 7: 1}, 
 'foo_2': {0: 0, 1: 1, 2: 0, 3: 0, 4: 1, 5: 0, 6: 0, 7: 0}, 
 'foo_3': {0: 0, 1: 0, 2: 1, 3: 0, 4: 0, 5: 0, 6: 1, 7: 0}, 
 'foo_4': {0: 0, 1: 0, 2: 0, 3: 1, 4: 0, 5: 0, 6: 0, 7: 0}}

cho duở trên, nhưng nó bảo tồn các loại cột . Ví dụ, trong trường hợp thử nghiệm ở trên,

du.equals(pd.DataFrame(du.to_dict()))
==> False

du.dtypesuint8pd.DataFrame(du.to_dict()).dtypesint64.


nó rõ ràng hơn, mặc dù tôi thừa nhận tôi không hiểu tại sao tôi muốn sử dụng nó hơnto_dict
Paul H

2
Bởi vì nó bảo tồn các loại cột. Cụ thể hơn , du.equals(eval(dput(df))).
sds
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.