Cách tạo các ví dụ về gấu trúc có thể tái tạo tốt

Nov 21 2013

Đã dành một lượng thời gian kha khá để xem cả thẻ rpandas 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ể tái tạo. Đây là điều mà cộng đồng R đã khuyến khích khá tốt, và nhờ những hướng dẫn như thế này , những người mới đến có thể nhận được một số trợ giúp trong việc tổng hợp 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ẽ gặp 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ụ có thể tái tạo tốt cho các pandascâu hỏi? Các khung dữ liệu đơn giản có thể được ghép lại với 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 ví dụ 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 của R , tạo ra tất cả các kết hợp có thể có của một số biến nhất định không?)
  • Dữ liệu MultiIndex hoặc Panel

Đối với các tập dữ liệu khó giả lập bằng cách sử dụng một vài dòng mã, có mã nào 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ơ cấu dữ liệu của mình không?

Trả lời

362 AndyHayden Nov 23 2013 at 13:19

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 * ví dụ nhỏ, hoặc dưới dạng mã 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 được" 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 đánh dấu Stack Overflow và sử dụng Ctrl+ K(hoặc thêm bốn dấu cách vào mỗi dòng) hoặc đặt ba dấu ngã ở trên và dưới mã của bạn với mã của bạn không có dấu:

    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 DataFrames ví dụ 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 tự tìm hiểu xem liệu bạn có thể tạo ra một DataFrame nhỏ thể hiện vấn đề bạn đang gặp phải hay không.

    * Mỗi quy tắc có một ngoại lệ, là rõ ràng là dành cho vấn đề hiệu suất ( trong trường hợp này chắc chắn sử dụng% timeit và có thể là% prun ), nơi mà bạn nên tạo (xem xét sử dụng np.random.seed vì vậy 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 chóng cho tôi" không hoàn toàn nằm trong chủ đề của trang web ...

  • viết ra kết quả 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ừ gì: 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 điều 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.

  • 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 ), đưa ra một bản tóm tắt:

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

    Các tài liệu của groupby không đưa ra bất kỳ ví dụ nào 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 bạn có cột Dấu thời gian có liên quan, ví dụ như bạn đang lấy mẫu lại hoặc thứ gì đó, thì hãy rõ ràng và áp dụng pd.to_datetimechúng để có biện pháp tốt **.

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

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

Những người xấu:

  • không bao gồm MultiIndex, mà chúng tôi không thể sao chép và dán (xem ở trên), đây là một loại than phiền với màn hình mặc định của gấu trúc nhưng vẫn gây khó chịu:

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

    Cách đúng là bao gồm một DataFrame thông thường với một set_indexlệnh 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ề nó là gì 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 lấy các con số (chúng là gì) ... kiểm tra kỹ xem chúng có đúng không.

  • Nếu mã của bạn gặp 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 nó quá ồn ào). Hiển thị số dòng (và dòng tương ứng của mã của bạn mà nó đang dựa vào).

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 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 mà chúng tôi nhận được: Tạo dữ liệu tương tự và xem liệu bạn có thể tái tạo sự cố (một cái gì đó nhỏ).

  • không giải thích tình huống một cách mơ hồ bằng lời nói, chẳng hạn như bạn có DataFrame "lớn", hãy đề cập đến một số tên cột đang chuyển (hãy đảm bảo không đề cập đến kiểu của chúng). Hãy thử và đi sâu vào chi tiết về điều gì đó hoàn toàn vô nghĩa nếu 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 rất tệ, sẽ dễ dàng hơn với những ví dụ nhỏ.

  • không bao gồm hơn 10 (100+ ??) dòng dữ liệu trước khi chuyển đế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 đang gây rắc rối cho bạn.

Dù sao, chúc bạn học Python, NumPy và Pandas thật vui vẻ!

77 JohnE May 24 2015 at 21:22

Cách tạo tập 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 khung dữ liệu mẫu. Pandas và (đặc biệt) numpy cung cấp cho bạn nhiều công cụ khác nhau để bạn 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ỉ với một vài dòng mã.

Sau khi nhập gấu trúc và gấu trúc, hãy đảm bảo cung cấp hạt giống ngẫu nhiên nếu bạn muốn mọi người có thể tái tạo 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ụ về bồn rửa nhà bếp

Đây là một ví dụ cho thấy nhiều điều bạn có thể làm. Tất cả các loại khung dữ liệu mẫu hữu ích có thể được tạo từ một tập hợp con của cái 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 nhóm và chỉ số 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 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 . Chúng sẽ cho phép bất kỳ số kích thước nào.
  3. Bạn có thể làm khá nhiều với np.random.choice. Ví dụ: trong cột g, chúng tôi có một lựa chọn ngẫu nhiên gồm 6 ngày từ năm 2011. Ngoài ra, bằng cách thiết lập, 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 nó 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ả mạo

Ngoài việc lấy các tập hợp con của đoạn mã trên, bạn có thể kết hợp thêm các kỹ thuật để thực hiện bất kỳ điều gì. Ví dụ: đây là một ví dụ ngắn kết hợp np.tiledate_rangeđể tạo dữ liệu mã cổ phiế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 tập 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
51 piRSquared Jul 20 2016 at 01:35

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

Lời khuyên tốt nhất của tôi khi đặt câu hỏi là đánh vào tâm lý của người trả lời câu hỏi. Là một trong những người đó, tôi có thể đưa ra cái nhìn sâu sắc về 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 người khác.

Động lực

Tôi có động lực để trả lời các câu hỏi vì một số 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 những nỗ lực của tôi để đền đáp, tôi thấy trang web này là một nguồn tài nguyên thậm chí còn mạnh mẽ hơn trước đây. Trả lời câu hỏi là một kinh nghiệm học hỏi đối với tôi và tôi muốn 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 . Tương tác kiểu này khiến tôi rất vui.
  3. Tôi thích điểm!
  4. Xem # 3.
  5. Tôi thích những vấn đề thú vị.

Tất cả những ý định thuần túy nhất của tôi đều tuyệt vời và tất cả, nhưng tôi đạt đượ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 tôi lựa chọn câu hỏi nào cần trả lời có một thành phần rất lớn của việc 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à xa vời và không giúp ích được gì cho 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 để giúp 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 câu hỏi đó với nỗ lực ít nhất có thể. Nếu tôi đang xem hai câu hỏi và một câu có mã, tôi có thể sao chép dán để tạo tất cả các biến mà tôi cần ... Tôi đang lấy câu đó! Tôi sẽ quay lại với cái khác nếu tôi có thời gian, có thể.

Lời khuyên chính

Giúp mọi người dễ dàng 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 lướt qua 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 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ụ thể. Chúng tôi muốn xem bạn đã làm gì 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ự mâu thuẫn trong mô tả bằng ngôn ngữ tự nhiên.
  • HÃY thể hiện những gì bạn mong đợi !!! Tôi phải ngồi xuống và thử mọi thứ. Tôi hầu như không bao giờ biết câu trả lời cho một câu hỏi nếu không thử một số thứ. Nếu tôi không thấy 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 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ự kết hợp của những gì người khác trên trang web nghĩ về tôi. Tôi cố gắng trở nên 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 gì đối với người hỏi, chúng ta nhớ các hành vi của người hỏi. Tôi nhớ nếu bạn không chọn câu trả lời và tán thành câu trả lời hay. 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 ảnh hưởng đến những câu hỏi mà tôi sẽ trả lời.


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

31 Alexander Sep 12 2015 at 14:06

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 sẽ í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ó vấn đề muốn được 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à những người khác sau đó có thể sử dụng để giúp giải quyết vấn đề của bạn.

Hướng dẫn do @Andy cung cấp để viết các câu hỏi hay về Gấu trúc 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ể xác minh .

Vui lòng nêu rõ câu hỏi của bạn 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 cố gắng đọc nó và cung cấp '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 ban đầu :

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 tôi trô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 sự cố sau ...

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

Làm thế nào để tôi sử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 trải qua 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 sao cho câu hỏi đó ở trên cùng, sau đó cung cấp các chi tiết cần thiết.

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

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

Tôi đã cố gắng tìm ra giải pháp bằng cách làm [đ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 sự cố sau ...

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

Đây là một số mã tối thiểu có thể tái tạo sự cố 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 THIẾT !!!

Đôi khi chỉ 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 do @JohnE đề xuất để tạo tập dữ liệu lớn hơn có thể được người khác sao chép. Sử dụng ví dụ của anh ấy để tạo DataFrame 100 hàng về 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 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 đảm bảo ẩn danh mọi dữ liệu nhạy cảm):

>>> 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ả về DataFrame (chỉ sử dụng các cột có liên quan). Điều này giúp những người khác kiểm tra kiểu dữ liệu của mỗi cột dễ dàng hơn và xác định các lỗi phổ biến khác (ví dụ: ngày là 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ó MultiIndex:

Nếu DataFrame của bạn có đa chỉ mục, 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
15 sds Dec 17 2016 at 00:57

Đây là phiên bản của tôi về dput- công cụ R tiêu chuẩn để tạo báo cáo có thể tái tạo - cho Gấu trúc DataFrame. Nó có thể sẽ thất bại đối với các khung phức tạp hơn, nhưng nó có vẻ hoạt động tốt 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 đầu ra dài dòng hơn nhiều so với 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))

vs

{'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.