Cara membuat contoh panda yang dapat direproduksi dengan baik

221

Setelah menghabiskan banyak waktu menonton keduanya dan tag pada SO, kesan yang saya dapatkan adalah bahwa pandaspertanyaan cenderung mengandung data yang dapat direproduksi. Ini adalah sesuatu yang mendorong komunitas R cukup baik, dan berkat panduan seperti ini , pendatang baru dapat memperoleh bantuan untuk mengumpulkan contoh-contoh ini. Orang-orang yang dapat membaca panduan ini dan kembali dengan data yang dapat direproduksi akan lebih beruntung mendapatkan jawaban atas pertanyaan mereka.

Bagaimana kita bisa membuat contoh yang dapat direproduksi untuk pandaspertanyaan? Kerangka data sederhana dapat disatukan, misalnya:

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

Tetapi banyak contoh dataset membutuhkan struktur yang lebih rumit, misalnya:

  • datetime indeks atau data
  • Beberapa variabel kategori (adakah yang setara dengan expand.grid()fungsi R , yang menghasilkan semua kemungkinan kombinasi dari beberapa variabel yang diberikan?)
  • Data MultiIndex atau Panel

Untuk kumpulan data yang sulit untuk dipermainkan menggunakan beberapa baris kode, adakah yang setara dengan R dput()yang memungkinkan Anda menghasilkan kode yang dapat di-tempel untuk meregenerasi struktur data Anda?

Marius
sumber
8
Jika Anda menyalin hasil pencetakan, sebagian besar penjawab waktu dapat menggunakan read_clipboard () ... kecuali untuk MultiIndex: s. Mengatakan itu, dikt adalah tambahan yang baik
Andy Hayden
8
Selain apa yang dikatakan Andy, saya pikir copy paste df.head(N).to_dict(), di mana Nbeberapa angka yang masuk akal adalah cara yang baik untuk pergi. Bonus +1 untuk menambahkan jeda baris cantik pada output. Untuk cap waktu, Anda biasanya hanya perlu menambahkan from pandas import Timestampke bagian atas kode.
Paul H

Jawaban:

323

Catatan: Ide-ide di sini cukup umum untuk Stack Overflow, memang pertanyaan .

Penafian: Menulis pertanyaan yang bagus adalah KERAS.

Yang baik:

  • jangan menyertakan * contoh kecil DataFrame, baik sebagai kode runnable:

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

    atau menjadikannya "salin dan tempel" menggunakan pd.read_clipboard(sep='\s\s+'), Anda dapat memformat teks untuk sorot Stack Overflow dan menggunakan Ctrl+ K(atau tambahkan empat spasi untuk setiap baris), atau tempatkan tiga tildes di atas dan di bawah kode Anda dengan kode Anda tanpa indentasi:

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

    uji pd.read_clipboard(sep='\s\s+')dirimu.

    * Saya benar-benar kecil , sebagian besar contoh DataFrames bisa kurang dari 6 baris kutipan , dan saya yakin saya bisa melakukannya dalam 5 baris. Bisakah Anda mereproduksi kesalahan dengan df = df.head(), jika tidak bermain-main untuk melihat apakah Anda bisa membuat DataFrame kecil yang menunjukkan masalah yang Anda hadapi.

    * Setiap aturan memiliki pengecualian, satu yang jelas adalah untuk masalah kinerja ( dalam hal ini pasti menggunakan% timeit dan mungkin% prun ), di mana Anda harus menghasilkan (mempertimbangkan menggunakan np.random.seed sehingga kita memiliki frame yang sama persis): df = pd.DataFrame(np.random.randn(100000000, 10)). Mengatakan itu, "buatkan kode ini cepat untukku" tidak sepenuhnya pada topik untuk situs ...

  • tuliskan hasil yang Anda inginkan (mirip dengan di atas)

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

    Jelaskan dari mana angka-angka itu berasal: angka 5 adalah jumlah dari kolom B untuk baris di mana A adalah 1.

  • jangan tunjukkan kode yang telah Anda coba:

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

    Tapi katakan apa yang salah: kolom A ada di indeks daripada kolom.

  • jangan tunjukkan bahwa Anda telah melakukan riset ( cari dokumen , cari StackOverflow ), berikan ringkasan:

    Docstring for sum hanya menyatakan "Hitung jumlah nilai grup"

    The docs groupby tidak memberikan contoh untuk ini.

    Selain: jawabannya di sini adalah untuk digunakan df.groupby('A', as_index=False).sum().

  • jika relevan bahwa Anda memiliki kolom Timestamp, misalnya Anda melakukan resampling atau semacamnya, maka jelaskan dan terapkan pd.to_datetimepadanya untuk ukuran yang baik **.

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

    ** Terkadang ini masalahnya sendiri: mereka adalah dawai.

Keburukan:

  • jangan menyertakan MultiIndex, yang tidak dapat kami salin dan tempel (lihat di atas), ini semacam keluhan dengan tampilan default panda tetapi tetap saja mengganggu:

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

    Cara yang benar adalah dengan memasukkan DataFrame biasa dengan set_indexpanggilan:

    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
    
  • berikan wawasan tentang apa itu ketika memberikan hasil yang Anda inginkan:

       B
    A   
    1  1
    5  0
    

    Jelaskan secara spesifik bagaimana Anda mendapatkan angka (berapa jumlahnya) ... periksa apakah benar.

  • Jika kode Anda menimbulkan kesalahan, sertakan seluruh jejak tumpukan (ini dapat diedit nanti jika terlalu berisik). Tampilkan nomor baris (dan baris yang sesuai dengan kode Anda yang dibesarkan).

Jelek:

  • jangan menautkan ke csv yang tidak dapat kami akses (idealnya tidak terhubung ke sumber eksternal sama sekali ...)

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

    Sebagian besar data adalah hak milik kami, dapatkan: Membuat data serupa dan melihat apakah Anda dapat mereproduksi masalah (sesuatu yang kecil).

  • jangan jelaskan situasinya secara samar dengan kata-kata, seperti Anda memiliki DataFrame yang "besar", sebutkan beberapa nama kolom secara sepintas (pastikan untuk tidak menyebutkan dtipnya). Cobalah dan masuk ke banyak detail tentang sesuatu yang sama sekali tidak berarti tanpa melihat konteks yang sebenarnya. Agaknya tidak ada yang akan membaca sampai akhir paragraf ini.

    Esai itu buruk, lebih mudah dengan contoh-contoh kecil.

  • jangan sertakan 10+ (100+ ??) baris data munging sebelum sampai ke pertanyaan Anda yang sebenarnya.

    Tolong, kita cukup melihat ini dalam pekerjaan sehari-hari kita. Kami ingin membantu, tapi tidak seperti ini ... .
    Potong intro, dan cukup tunjukkan DataFrames yang relevan (atau versi kecil dari mereka) pada langkah yang menyebabkan Anda kesulitan.

Ngomong-ngomong, bersenang-senanglah belajar Python, NumPy, dan Panda!

Andy Hayden
sumber
30
+1 untuk pd.read_clipboard(sep='\s\s+')tipnya. Ketika saya memposting pertanyaan SO yang membutuhkan dataframe khusus tetapi mudah dibagikan, seperti ini saya buat dalam excel, salin ke clipboard saya, lalu perintahkan SOers untuk melakukan hal yang sama. Menghemat banyak waktu!
zelusp
1
yang pd.read_clipboard(sep='\s\s+')saran tampaknya tidak bekerja jika Anda menggunakan Python di server jauh, yang mana banyak set data yang besar hidup.
user5359531
1
Mengapa pd.read_clipboard(sep='\s\s+'), dan bukan yang lebih sederhana pd.read_clipboard()(dengan default ‘s+’)? Yang pertama perlu minimal 2 spasi karakter, yang dapat menyebabkan masalah jika hanya ada 1 (misalnya melihat seperti di @JohnE 's jawaban ).
MarianD
3
@MarianD alasan mengapa \ s + begitu populer adalah bahwa sering ada satu misalnya dalam nama kolom, tetapi beberapa lebih jarang, dan keluaran panda dengan baik memasukkan setidaknya dua di antara kolom. Karena ini hanya untuk dataset mainan / kecil, itu cukup kuat / mayoritas kasus. Catatan: tab yang dipisahkan akan menjadi cerita yang berbeda, meskipun stackoverflow menggantikan tab dengan spasi, tetapi jika Anda memiliki tsv maka gunakan saja \ t.
Andy Hayden
3
Ugh, saya selalu menggunakan pd.read_clipboard(), ketika spasi, saya lakukan pd.read_clipboard(sep='\s+{2,}', engine='python'):: P
U10-Forward
72

Cara membuat dataset sampel

Ini terutama untuk memperluas jawaban @ AndyHayden dengan memberikan contoh bagaimana Anda bisa membuat kerangka data sampel. Panda dan (terutama) numpy memberi Anda berbagai alat untuk ini sehingga Anda umumnya dapat membuat faksimili yang wajar dari setiap dataset nyata hanya dengan beberapa baris kode.

Setelah mengimpor numpy dan panda, pastikan untuk memberikan benih acak jika Anda ingin orang-orang dapat mereproduksi data dan hasil Anda secara tepat.

import numpy as np
import pandas as pd

np.random.seed(123)

Contoh wastafel dapur

Berikut ini contoh yang menunjukkan berbagai hal yang dapat Anda lakukan. Semua jenis kerangka data sampel yang berguna dapat dibuat dari subset ini:

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) 
    })

Ini menghasilkan:

          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

Beberapa catatan:

  1. np.repeatdan np.tile(kolom ddan e) sangat berguna untuk membuat grup dan indeks secara teratur. Untuk 2 kolom, ini dapat digunakan untuk dengan mudah menduplikasi r's expand.grid()tetapi juga lebih fleksibel dalam kemampuan untuk memberikan subset dari semua permutasi. Namun, untuk 3 kolom atau lebih, sintaks dengan cepat menjadi berat.
  2. Untuk penggantian yang lebih langsung untuk r's expand.grid()lihat itertoolssolusi di buku masak panda atau np.meshgridsolusi yang ditunjukkan di sini . Itu akan memungkinkan sejumlah dimensi.
  3. Anda dapat melakukan cukup banyak dengan np.random.choice. Misalnya, dalam kolom g, kami memiliki 6 pilihan acak mulai dari 2011. Selain itu, dengan menetapkan replace=Falsekami dapat memastikan bahwa tanggal ini unik - sangat berguna jika kami ingin menggunakan ini sebagai indeks dengan nilai unik.

Data pasar saham palsu

Selain mengambil himpunan bagian dari kode di atas, Anda dapat lebih lanjut menggabungkan teknik untuk melakukan apa saja. Misalnya, berikut adalah contoh singkat yang menggabungkan np.tiledan date_rangemembuat sampel data ticker untuk 4 saham yang mencakup tanggal yang sama:

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) })

Sekarang kami memiliki dataset dataset dengan 100 baris (25 tanggal per ticker), tetapi kami hanya menggunakan 4 baris untuk melakukannya, sehingga memudahkan semua orang untuk mereproduksi tanpa menyalin dan menempelkan 100 baris kode. Anda kemudian dapat menampilkan himpunan bagian dari data jika itu membantu menjelaskan pertanyaan Anda:

>>> 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
JohnE
sumber
2
Jawaban yang bagus Setelah menulis pertanyaan ini, saya benar-benar menulis implementasi yang sangat singkat dan sederhana expand.grid()yang termasuk dalam buku masak panda , Anda dapat memasukkannya dalam jawaban Anda juga. Jawaban Anda menunjukkan cara membuat set data yang lebih kompleks daripada yang expand_grid()bisa ditangani oleh fungsi saya , yang bagus.
Marius
46

Diary of an Answerer

Saran terbaik saya untuk mengajukan pertanyaan adalah dengan bermain pada psikologi orang-orang yang menjawab pertanyaan. Menjadi salah satu dari orang-orang itu, saya dapat memberikan wawasan mengapa saya menjawab pertanyaan tertentu dan mengapa saya tidak menjawab orang lain.

Motivasi

Saya termotivasi untuk menjawab pertanyaan karena beberapa alasan

  1. Stackoverflow.com telah menjadi sumber yang sangat berharga bagi saya. Saya ingin memberi kembali.
  2. Dalam upaya saya untuk memberi kembali, saya telah menemukan situs ini menjadi sumber daya yang bahkan lebih kuat dari sebelumnya. Menjawab pertanyaan adalah pengalaman belajar bagi saya dan saya suka belajar. Baca jawaban dan komentar ini dari dokter hewan lain . Interaksi semacam ini membuat saya bahagia.
  3. Saya suka poin!
  4. Lihat # 3.
  5. Saya suka masalah yang menarik.

Semua niat saya yang paling bagus dan bagus, tapi saya mendapatkan kepuasan itu jika saya menjawab 1 pertanyaan atau 30. Apa yang mendorong pilihan saya untuk pertanyaan yang dijawab memiliki komponen besar pemaksimalan poin.

Saya juga akan menghabiskan waktu untuk masalah-masalah menarik tetapi itu sedikit dan jarang dan tidak membantu penanya yang membutuhkan solusi untuk pertanyaan yang tidak menarik. Taruhan terbaik Anda untuk membuat saya menjawab pertanyaan adalah melayani pertanyaan itu di atas piring agar saya bisa menjawabnya dengan upaya sesedikit mungkin. Jika saya melihat dua pertanyaan dan satu memiliki kode saya dapat menyalin tempel untuk membuat semua variabel yang saya butuhkan ... Saya mengambil satu itu! Saya akan kembali ke yang lain jika saya punya waktu, mungkin.

Nasihat Utama

Permudah orang-orang menjawab pertanyaan.

  • Berikan kode yang menciptakan variabel yang diperlukan.
  • Minimalkan kode itu. Jika mata saya berkaca-kaca ketika saya melihat posting, saya ke pertanyaan berikutnya atau kembali ke apa pun yang saya lakukan.
  • Pikirkan tentang apa yang Anda minta dan spesifik. Kami ingin melihat apa yang telah Anda lakukan karena bahasa alami (Inggris) tidak tepat dan membingungkan. Sampel kode dari apa yang telah Anda coba membantu menyelesaikan ketidakkonsistenan dalam deskripsi bahasa alami.
  • TOLONG tunjukkan apa yang anda harapkan !!! Saya harus duduk dan mencoba berbagai hal. Saya hampir tidak pernah tahu jawaban pertanyaan tanpa mencoba beberapa hal. Jika saya tidak melihat contoh dari apa yang Anda cari, saya mungkin meneruskan pertanyaan karena saya merasa tidak ingin menebak.

Reputasi Anda lebih dari sekadar reputasi Anda.

Saya suka poin (saya sebutkan di atas). Tetapi poin-poin itu tidak benar-benar reputasi saya. Reputasi saya yang sebenarnya adalah gabungan dari apa yang orang lain pikirkan tentang saya di situs. Saya berusaha untuk bersikap adil dan jujur ​​dan saya berharap orang lain dapat melihatnya. Apa artinya itu bagi seorang penanya adalah, kita mengingat perilaku penanya. Jika Anda tidak memilih jawaban dan memilih jawaban yang baik, saya ingat. Jika Anda berperilaku dengan cara yang tidak saya sukai atau dengan cara yang saya sukai, saya ingat. Ini juga memainkan pertanyaan yang akan saya jawab.


Ngomong-ngomong, aku mungkin bisa melanjutkan, tapi aku akan mengampuni kalian yang benar-benar membaca ini.

piRquared
sumber
26

Tantangan Salah satu aspek paling menantang dalam menjawab pertanyaan SO adalah waktu yang diperlukan untuk menciptakan kembali masalah (termasuk data). Pertanyaan yang tidak memiliki cara yang jelas untuk mereproduksi data cenderung tidak dijawab. Karena Anda meluangkan waktu untuk menulis pertanyaan dan Anda memiliki masalah yang ingin Anda bantu, Anda dapat dengan mudah membantu diri sendiri dengan memberikan data yang kemudian dapat digunakan orang lain untuk membantu menyelesaikan masalah Anda.

Instruksi yang diberikan oleh @Andy untuk menulis pertanyaan Pandas yang baik adalah tempat yang bagus untuk memulai. Untuk informasi lebih lanjut, lihat cara bertanya dan cara membuat contoh Minimal, Lengkap, dan dapat diverifikasi .

Harap jelaskan pertanyaan Anda di muka. Setelah meluangkan waktu untuk menulis pertanyaan Anda dan kode sampel apa pun, cobalah untuk membacanya dan memberikan 'Ringkasan Eksekutif' untuk pembaca Anda yang merangkum masalah dan dengan jelas menyatakan pertanyaan.

Pertanyaan asli :

Saya punya data ini ...

Aku ingin melakukan ini...

Saya ingin hasil saya terlihat seperti ini ...

Namun, ketika saya mencoba melakukan ini, saya mendapatkan masalah berikut ...

Saya sudah mencoba mencari solusi dengan melakukan [ini] dan [itu].

Bagaimana saya memperbaikinya?

Bergantung pada jumlah data, kode sampel, dan tumpukan kesalahan yang disediakan, pembaca harus melangkah jauh sebelum memahami apa masalahnya. Coba nyatakan kembali pertanyaan Anda sehingga pertanyaan itu sendiri ada di atas, dan kemudian berikan rincian yang diperlukan.

Pertanyaan yang Direvisi :

Qustion: Bagaimana saya bisa melakukan ini?

Saya sudah mencoba mencari solusi dengan melakukan [ini] dan [itu].

Ketika saya mencoba melakukan [ini], saya mendapatkan masalah berikut ...

Saya ingin hasil akhir saya terlihat seperti ini ...

Berikut adalah beberapa kode minimal yang dapat mereproduksi masalah saya ...

Dan berikut ini cara membuat ulang data sampel saya: df = pd.DataFrame({'A': [...], 'B': [...], ...})

MEMBERIKAN DATA SAMPEL JIKA DIPERLUKAN !!!

Terkadang hanya kepala atau ekor dari DataFrame yang dibutuhkan. Anda juga dapat menggunakan metode yang diusulkan oleh @JohnE untuk membuat kumpulan data yang lebih besar yang dapat direproduksi oleh orang lain. Menggunakan contohnya untuk menghasilkan DataFrame 100 baris harga saham:

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) })

Jika ini adalah data aktual Anda, Anda mungkin hanya ingin menyertakan kepala dan / atau ujung kerangka data sebagai berikut (pastikan untuk menganonimkan data sensitif apa pun):

>>> 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'}}

Anda mungkin juga ingin memberikan deskripsi tentang DataFrame (hanya menggunakan kolom yang relevan). Ini memudahkan orang lain untuk memeriksa tipe data setiap kolom dan mengidentifikasi kesalahan umum lainnya (misalnya tanggal sebagai string vs datetime64 vs objek):

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)

CATATAN: Jika DataFrame Anda memiliki MultiIndex:

Jika DataFrame Anda memiliki multiindex, Anda harus mengatur ulang terlebih dahulu sebelum menelepon to_dict. Anda kemudian perlu membuat ulang indeks menggunakan 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
Alexander
sumber
12

Ini adalah versi saya dput- alat R standar untuk menghasilkan laporan yang dapat direproduksi - untuk Pandas DataFrames. Mungkin akan gagal untuk frame yang lebih kompleks, tetapi tampaknya melakukan pekerjaan dalam kasus sederhana:

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)

sekarang,

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)))

Perhatikan bahwa ini menghasilkan keluaran verbose yang jauh lebih banyak daripada DataFrame.to_dict, misalnya,

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}}

untuk di duatas, tetapi mempertahankan jenis kolom . Misalnya, dalam kasus uji di atas,

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

karena du.dtypesini uint8dan pd.DataFrame(du.to_dict()).dtypesitu int64.

sds
sumber
lebih jelas, meskipun saya akui saya tidak mengerti mengapa saya ingin menggunakannyato_dict
Paul H
2
Karena mempertahankan jenis kolom. Lebih khusus lagi du.equals(eval(dput(df))),.
sds