วิธีสร้างตัวอย่างแพนด้าที่ทำซ้ำได้ดี
หลังจากใช้เวลาพอสมควรในการดูทั้งแท็กrและแพนด้าใน SO ความประทับใจที่ฉันได้รับคือpandas
คำถามมีโอกาสน้อยที่จะมีข้อมูลที่ทำซ้ำได้ นี่เป็นสิ่งที่ชุมชน R ให้กำลังใจค่อนข้างดีและต้องขอบคุณคำแนะนำเช่นนี้ผู้มาใหม่สามารถขอความช่วยเหลือในการรวบรวมตัวอย่างเหล่านี้ได้ ผู้ที่สามารถอ่านคู่มือเหล่านี้และกลับมาพร้อมกับข้อมูลที่ทำซ้ำได้มักจะโชคดีกว่ามากที่จะได้รับคำตอบสำหรับคำถามของพวกเขา
เราจะสร้างตัวอย่างที่ทำซ้ำได้ดีสำหรับpandas
คำถามได้อย่างไร สามารถรวมดาต้าเฟรมอย่างง่ายเข้าด้วยกันเช่น:
import pandas as pd
df = pd.DataFrame({'user': ['Bob', 'Jane', 'Alice'],
'income': [40000, 50000, 42000]})
แต่ชุดข้อมูลตัวอย่างจำนวนมากต้องการโครงสร้างที่ซับซ้อนมากขึ้นเช่น:
datetime
ดัชนีหรือข้อมูล- ตัวแปรเชิงหมวดหมู่หลายตัว (มี
expand.grid()
ฟังก์ชันเทียบเท่ากับ R ซึ่งสร้างชุดค่าผสมที่เป็นไปได้ทั้งหมดของตัวแปรที่กำหนดหรือไม่) - ข้อมูล MultiIndex หรือ Panel
สำหรับชุดข้อมูลที่ยากต่อการจำลองโดยใช้โค้ดไม่กี่บรรทัดมี R dput()
ที่ช่วยให้คุณสร้างโค้ดที่คัดลอกวางได้เพื่อสร้างโครงสร้างข้อมูลของคุณใหม่หรือไม่
คำตอบ
หมายเหตุ: ความคิดที่นี่มีทั่วไปสวยสำหรับกองมากเกินจริงคำถาม
คำเตือน: การเขียนคำถามที่ดีนั้นยาก
ดี:
รวม DataFrame ตัวอย่างขนาดเล็ก * เป็นโค้ดที่รันได้:
In [1]: df = pd.DataFrame([[1, 2], [1, 3], [4, 6]], columns=['A', 'B'])
หรือทำให้เป็น "คัดลอกและวางได้" โดยใช้
pd.read_clipboard(sep='\s\s+')
คุณสามารถจัดรูปแบบข้อความสำหรับไฮไลต์ Stack Overflow และใช้Ctrl+ K(หรือเพิ่มช่องว่างสี่ช่องต่อบรรทัดแต่ละบรรทัด) หรือวางเครื่องหมายทิลด์สามตัวไว้ด้านบนและด้านล่างโค้ดของคุณโดยไม่เยื้องโค้ด:In [2]: df Out[2]: A B 0 1 2 1 1 3 2 4 6
ทดสอบ
pd.read_clipboard(sep='\s\s+')
ตัวเอง* ฉันหมายความว่าเล็กจริงๆDataFrames ตัวอย่างส่วนใหญ่อาจจำเป็นต้องมีการอ้างอิงน้อยกว่า 6 แถวและฉันพนันได้เลยว่าฉันทำได้ 5 แถว คุณสามารถสร้างข้อผิดพลาดซ้ำ
df = df.head()
ได้หรือไม่หากไม่ได้ลองทำเพื่อดูว่าคุณสามารถสร้าง DataFrame ขนาดเล็กที่แสดงปัญหาที่คุณกำลังเผชิญอยู่ได้หรือไม่* กฎทุกคนมีข้อยกเว้นที่เห็นได้ชัดหนึ่งสำหรับปัญหาประสิทธิภาพการทำงาน ( ซึ่งในกรณีนี้แน่นอนใช้ timeit% และอาจ% prun ) ที่คุณควรสร้าง (พิจารณาใช้ np.random.seed
df = pd.DataFrame(np.random.randn(100000000, 10))
เพื่อให้เรามีกรอบเดียวกันแน่นอน): บอกว่า "ทำให้โค้ดนี้เร็วสำหรับฉัน" ไม่ได้อยู่ในหัวข้อสำหรับเว็บไซต์อย่างเคร่งครัด ...เขียนผลลัพธ์ที่คุณต้องการ (คล้ายกับด้านบน)
In [3]: iwantthis Out[3]: A B 0 1 5 1 4 6
อธิบายว่าตัวเลขมาจากอะไร: 5 คือผลรวมของคอลัมน์ B สำหรับแถวที่ A คือ 1
แสดงรหัสที่คุณได้ลอง:
In [4]: df.groupby('A').sum() Out[4]: B A 1 5 4 6
แต่บอกว่าอะไรไม่ถูกต้อง: คอลัมน์ A อยู่ในดัชนีแทนที่จะเป็นคอลัมน์
จะแสดงที่คุณได้ทำวิจัยบางอย่าง ( ค้นหาเอกสาร , ค้นหา StackOverflow ) ให้สรุป:
docstring สำหรับ sum ระบุว่า "คำนวณผลรวมของค่ากลุ่ม"
เอกสาร GroupByไม่ให้ตัวอย่างใด ๆ นี้
นอกเหนือ:
df.groupby('A', as_index=False).sum()
คำตอบที่นี่คือการใช้งานหากมีความเกี่ยวข้องว่าคุณมีคอลัมน์การประทับเวลาเช่นคุณกำลังสุ่มตัวอย่างใหม่หรืออะไรบางอย่างให้ชัดเจนและนำ
pd.to_datetime
ไปใช้เพื่อการวัดที่ดี **df['date'] = pd.to_datetime(df['date']) # this column ought to be date..
** บางครั้งนี่เป็นปัญหาเอง: พวกเขาเป็นสตริง
สิ่งที่ไม่ดี:
อย่ารวม MultiIndex ซึ่งเราไม่สามารถคัดลอกและวางได้ (ดูด้านบน) นี่เป็นข้อข้องใจกับการแสดงผลเริ่มต้นของแพนด้า แต่ก็น่ารำคาญ:
In [11]: df Out[11]: C A B 1 2 3 2 6
วิธีที่ถูกต้องคือการรวม DataFrame ธรรมดาเข้ากับการ
set_index
โทร: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
ให้ข้อมูลเชิงลึกว่ามันคืออะไรเมื่อให้ผลลัพธ์ที่คุณต้องการ:
B A 1 1 5 0
เจาะจงว่าคุณได้ตัวเลขอย่างไร (คืออะไร) ... ตรวจสอบอีกครั้งว่าถูกต้อง
หากรหัสของคุณแสดงข้อผิดพลาดให้รวมการติดตามสแต็กทั้งหมด (สามารถแก้ไขได้ในภายหลังหากมีเสียงดังเกินไป) แสดงหมายเลขบรรทัด (และบรรทัดที่สอดคล้องกันของรหัสของคุณที่เพิ่มขึ้น)
น่าเกลียด:
อย่าเชื่อมโยงไปยัง csv ที่เราไม่สามารถเข้าถึงได้ (ควรอย่าเชื่อมโยงไปยังแหล่งภายนอกเลย ... )
df = pd.read_csv('my_secret_file.csv') # ideally with lots of parsing options
ข้อมูลส่วนใหญ่เป็นกรรมสิทธิ์ที่เราได้รับ: สร้างข้อมูลที่คล้ายกันและดูว่าคุณสามารถสร้างปัญหาซ้ำได้หรือไม่ (สิ่งเล็ก ๆ )
อย่าอธิบายสถานการณ์ด้วยคำพูดคลุมเครือเช่นคุณมี DataFrame ซึ่ง "ใหญ่" ให้พูดถึงชื่อคอลัมน์บางส่วนในการส่งผ่าน (อย่าพูดถึงประเภทของคอลัมน์นั้น ๆ ) ลองลงรายละเอียดเกี่ยวกับสิ่งที่ไม่มีความหมายโดยสิ้นเชิงโดยไม่ต้องดูบริบทที่แท้จริง คงไม่มีใครแม้แต่จะอ่านจนจบย่อหน้านี้
บทความไม่ดีมันง่ายกว่าด้วยตัวอย่างเล็ก ๆ
อย่ารวมบรรทัดข้อมูล 10+ (100+ ??) ก่อนที่จะไปถึงคำถามจริงของคุณ
ได้โปรดเราเห็นสิ่งนี้เพียงพอแล้วในงานประจำวันของเรา เราต้องการที่จะช่วยเหลือ แต่ไม่ได้เช่นนี้ ...
ตัดคำนำและแสดง DataFrames ที่เกี่ยวข้อง (หรือเวอร์ชันเล็ก ๆ ) ในขั้นตอนที่ทำให้คุณเดือดร้อน
ยังไงก็ตามขอให้สนุกกับการเรียนรู้ Python, NumPy และ Pandas!
วิธีสร้างชุดข้อมูลตัวอย่าง
นี่คือการขยายคำตอบของ @ AndyHayden เป็นหลักโดยการให้ตัวอย่างวิธีสร้างดาต้าเฟรมตัวอย่าง Pandas และ (โดยเฉพาะ) numpy ให้เครื่องมือที่หลากหลายสำหรับสิ่งนี้ซึ่งโดยทั่วไปคุณสามารถสร้างโทรสารที่เหมาะสมของชุดข้อมูลจริงได้โดยใช้โค้ดเพียงไม่กี่บรรทัด
หลังจากนำเข้า numpy และ pandas อย่าลืมใส่เมล็ดพันธุ์แบบสุ่มหากคุณต้องการให้คนอื่น ๆ สามารถทำซ้ำข้อมูลและผลลัพธ์ของคุณได้อย่างถูกต้อง
import numpy as np
import pandas as pd
np.random.seed(123)
ตัวอย่างอ่างล้างจานในครัว
นี่คือตัวอย่างที่แสดงสิ่งต่างๆที่คุณทำได้ สามารถสร้างดาต้าเฟรมตัวอย่างที่มีประโยชน์ทุกประเภทจากส่วนย่อยของสิ่งนี้:
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)
})
สิ่งนี้ก่อให้เกิด:
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
หมายเหตุบางประการ:
np.repeat
และnp.tile
(คอลัมน์d
และe
) มีประโยชน์มากสำหรับการสร้างกลุ่มและดัชนีอย่างสม่ำเสมอ สำหรับ 2 คอลัมน์นี้สามารถใช้เพื่อทำซ้ำ r ได้อย่างง่ายดายexpand.grid()
แต่ยังมีความยืดหยุ่นมากกว่าในความสามารถในการจัดเตรียมส่วนย่อยของการเรียงสับเปลี่ยนทั้งหมด อย่างไรก็ตามสำหรับ 3 คอลัมน์ขึ้นไปไวยากรณ์จะไม่สะดวกอย่างรวดเร็ว- สำหรับแทนโดยตรงมากขึ้นสำหรับอาร์เอส
expand.grid()
ดูitertools
วิธีการแก้ปัญหาในหมีแพนด้าตำราหรือnp.meshgrid
วิธีการแก้ปัญหาที่แสดงที่นี่ ซึ่งจะอนุญาตให้มีมิติข้อมูลจำนวนเท่าใดก็ได้ - คุณสามารถทำได้ไม่น้อยกับ
np.random.choice
. ตัวอย่างเช่นในคอลัมน์g
เรามีการเลือกวันที่ 6 แบบสุ่มจากปี 2011 นอกจากนี้การตั้งค่าทำให้replace=False
เรามั่นใจได้ว่าวันที่เหล่านี้ไม่ซ้ำกันซึ่งมีประโยชน์มากหากเราต้องการใช้เป็นดัชนีที่มีค่าเฉพาะ
ข้อมูลตลาดหุ้นปลอม
นอกเหนือจากการใช้ชุดย่อยของโค้ดข้างต้นแล้วคุณยังสามารถรวมเทคนิคเพิ่มเติมเพื่อทำอะไรก็ได้ ตัวอย่างเช่นนี่คือตัวอย่างสั้น ๆ ที่รวมnp.tile
และdate_range
สร้างข้อมูลสัญลักษณ์ตัวอย่างสำหรับหุ้น 4 ตัวที่ครอบคลุมวันที่เดียวกัน:
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) })
ตอนนี้เรามีชุดข้อมูลตัวอย่างที่มี 100 บรรทัด (25 วันที่ต่อทิกเกอร์) แต่เราใช้เพียง 4 บรรทัดในการทำทำให้คนอื่น ๆ ทำซ้ำได้ง่ายโดยไม่ต้องคัดลอกและวางโค้ด 100 บรรทัด จากนั้นคุณสามารถแสดงชุดย่อยของข้อมูลได้หากช่วยอธิบายคำถามของคุณ:
>>> 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
ไดอารี่ของผู้ตอบ
คำแนะนำที่ดีที่สุดสำหรับการถามคำถามคือการใช้จิตวิทยาของคนที่ตอบคำถาม ในฐานะหนึ่งในคนเหล่านั้นฉันสามารถให้ข้อมูลเชิงลึกว่าทำไมฉันจึงตอบคำถามบางคำถามและทำไมฉันไม่ตอบคำถามคนอื่น
แรงจูงใจ
ฉันมีแรงจูงใจที่จะตอบคำถามด้วยเหตุผลหลายประการ
- Stackoverflow.com เป็นทรัพยากรที่มีค่าอย่างยิ่งสำหรับฉัน ฉันอยากจะให้กลับ
- ในความพยายามของฉันที่จะตอบแทนฉันพบว่าไซต์นี้เป็นแหล่งข้อมูลที่ทรงพลังยิ่งกว่าเดิม การตอบคำถามเป็นประสบการณ์การเรียนรู้สำหรับฉันและฉันชอบเรียนรู้ อ่านคำตอบนี้และแสดงความคิดเห็นจากสัตว์แพทย์อีก การโต้ตอบแบบนี้ทำให้ฉันมีความสุข
- ชอบคะแนน!
- ดู # 3
- ฉันชอบปัญหาที่น่าสนใจ
ความตั้งใจอันบริสุทธิ์ทั้งหมดของฉันนั้นยอดเยี่ยมมากและทั้งหมดนี้ แต่ฉันจะได้รับความพึงพอใจนั้นถ้าฉันตอบคำถาม 1 ข้อหรือ 30 ข้อ สิ่งที่ผลักดันตัวเลือกของฉันสำหรับคำถามที่จะตอบนั้นมีส่วนสำคัญในการเพิ่มประเด็น
ฉันจะใช้เวลากับปัญหาที่น่าสนใจเช่นกัน แต่มีน้อยมากและไม่ได้ช่วยผู้ถามที่ต้องการคำตอบสำหรับคำถามที่ไม่น่าสนใจ ทางออกที่ดีที่สุดของคุณในการให้ฉันตอบคำถามคือการตอบคำถามนั้นบนแผ่นเสียงที่สุกเพื่อให้ฉันตอบคำถามโดยใช้ความพยายามให้น้อยที่สุด หากฉันกำลังดูคำถามสองข้อและอีกข้อหนึ่งมีโค้ดฉันสามารถคัดลอกวางเพื่อสร้างตัวแปรทั้งหมดที่ฉันต้องการ ... ฉันกำลังรับข้อนั้น! ฉันจะกลับมาหาคนอื่นถ้าฉันมีเวลาอาจจะ
คำแนะนำหลัก
ทำให้ง่ายสำหรับคนที่ตอบคำถาม
- ระบุรหัสที่สร้างตัวแปรที่ต้องการ
- ย่อโค้ดนั้น หากดวงตาของฉันจ้องมองไปที่โพสต์ฉันจะไปที่คำถามต่อไปหรือกลับไปหาสิ่งอื่นที่ฉันกำลังทำอยู่
- นึกถึงสิ่งที่คุณกำลังถามและเจาะจง เราต้องการทราบว่าคุณได้ทำอะไรไปบ้างเนื่องจากภาษาธรรมชาติ (อังกฤษ) ไม่ตรงประเด็นและสับสน ตัวอย่างโค้ดของสิ่งที่คุณพยายามช่วยแก้ไขความไม่สอดคล้องกันในคำอธิบายภาษาธรรมชาติ
- โปรดแสดงสิ่งที่คุณคาดหวัง !!! ฉันต้องนั่งลงและลองทำสิ่งต่างๆ ฉันแทบไม่เคยรู้คำตอบสำหรับคำถามโดยไม่ได้ลองทำบางอย่าง ถ้าฉันไม่เห็นตัวอย่างของสิ่งที่คุณกำลังมองหาฉันอาจจะส่งคำถามนี้ไปเพราะฉันรู้สึกไม่อยากเดา
ชื่อเสียงของคุณเป็นมากกว่าชื่อเสียงของคุณ
ฉันชอบคะแนน (ฉันได้กล่าวไว้ข้างต้น) แต่ประเด็นเหล่านั้นไม่ใช่ชื่อเสียงของฉันจริงๆ ชื่อเสียงที่แท้จริงของฉันคือการผสมผสานสิ่งที่คนอื่น ๆ ในไซต์คิดกับฉัน ฉันพยายามที่จะมีความยุติธรรมและซื่อสัตย์และฉันหวังว่าคนอื่นจะเห็นสิ่งนั้น สิ่งที่หมายถึงสำหรับผู้ถามคือเราจำพฤติกรรมของผู้ถาม หากคุณไม่เลือกคำตอบและโหวตคำตอบที่ดีฉันจำได้ หากคุณประพฤติในสิ่งที่ฉันไม่ชอบหรือในแบบที่ฉันชอบฉันจำไว้ นอกจากนี้ยังเล่นเป็นคำถามที่ฉันจะตอบ
อย่างไรก็ตามฉันสามารถไปต่อได้ แต่ฉันจะช่วยพวกคุณทุกคนที่อ่านเรื่องนี้จริงๆ
ความท้าทายหนึ่งในแง่มุมที่ท้าทายที่สุดในการตอบคำถาม SO คือเวลาที่ใช้ในการสร้างปัญหาขึ้นใหม่ (รวมถึงข้อมูล) คำถามที่ไม่มีวิธีที่ชัดเจนในการสร้างข้อมูลซ้ำมีโอกาสน้อยที่จะได้รับคำตอบ เนื่องจากคุณใช้เวลาในการเขียนคำถามและคุณมีปัญหาที่ต้องการความช่วยเหลือคุณสามารถช่วยเหลือตัวเองได้อย่างง่ายดายโดยให้ข้อมูลที่ผู้อื่นสามารถใช้เพื่อช่วยแก้ปัญหาของคุณได้
คำแนะนำจาก @Andy สำหรับการเขียนคำถาม Pandas ที่ดีเป็นจุดเริ่มต้นที่ดีเยี่ยม สำหรับข้อมูลเพิ่มเติมโปรดดูวิธีการถามและวิธีสร้างตัวอย่างน้อยที่สุดสมบูรณ์และตรวจสอบได้
โปรดระบุคำถามของคุณให้ชัดเจนล่วงหน้า หลังจากสละเวลาเขียนคำถามและโค้ดตัวอย่างแล้วให้ลองอ่านและจัดเตรียม 'บทสรุปสำหรับผู้บริหาร' สำหรับผู้อ่านของคุณซึ่งสรุปปัญหาและระบุคำถามไว้อย่างชัดเจน
คำถามเดิม :
ฉันมีข้อมูลนี้ ...
ฉันอยากทำสิ่งนี้ ...
ฉันต้องการให้ผลลัพธ์เป็นแบบนี้ ...
อย่างไรก็ตามเมื่อฉันพยายามทำ [สิ่งนี้] ฉันพบปัญหาต่อไปนี้ ...
ฉันพยายามหาวิธีแก้ไขโดยทำ [this] และ [that]
ฉันจะแก้ไขได้อย่างไร?
ขึ้นอยู่กับจำนวนข้อมูลโค้ดตัวอย่างและสแต็กข้อผิดพลาดที่มีให้ผู้อ่านต้องใช้เวลานานก่อนที่จะเข้าใจว่าปัญหาคืออะไร ลองตั้งคำถามใหม่เพื่อให้คำถามนั้นอยู่ด้านบนจากนั้นให้รายละเอียดที่จำเป็น
คำถามที่แก้ไข :
คำถาม: ฉันจะทำ [สิ่งนี้] ได้อย่างไร?
ฉันพยายามหาวิธีแก้ไขโดยทำ [this] และ [that]
เมื่อฉันพยายามทำ [สิ่งนี้] ฉันพบปัญหาต่อไปนี้ ...
ฉันต้องการให้ผลลัพธ์สุดท้ายเป็นแบบนี้ ...
นี่คือรหัสขั้นต่ำที่สามารถทำให้เกิดปัญหาของฉัน ...
และนี่คือวิธีสร้างข้อมูลตัวอย่างของฉันใหม่:
df = pd.DataFrame({'A': [...], 'B': [...], ...})
ให้ข้อมูลตัวอย่างหากจำเป็น !!!
บางครั้งแค่ส่วนหัวหรือส่วนท้ายของ DataFrame ก็เป็นสิ่งที่จำเป็น คุณยังสามารถใช้วิธีการที่เสนอโดย @JohnE เพื่อสร้างชุดข้อมูลขนาดใหญ่ที่ผู้อื่นสามารถทำซ้ำได้ ใช้ตัวอย่างของเขาเพื่อสร้าง DataFrame 100 แถวของราคาหุ้น:
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) })
หากนี่เป็นข้อมูลจริงของคุณคุณอาจต้องรวมส่วนหัวและ / หรือส่วนท้ายของดาต้าเฟรมดังต่อไปนี้ (อย่าลืมระบุข้อมูลที่ละเอียดอ่อนใด ๆ ):
>>> 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'}}
คุณอาจต้องการระบุคำอธิบายของ DataFrame (โดยใช้เฉพาะคอลัมน์ที่เกี่ยวข้อง) สิ่งนี้ช่วยให้ผู้อื่นตรวจสอบชนิดข้อมูลของแต่ละคอลัมน์ได้ง่ายขึ้นและระบุข้อผิดพลาดทั่วไปอื่น ๆ (เช่นวันที่เป็นสตริงเทียบกับ datetime64 เทียบกับวัตถุ):
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)
หมายเหตุ: หาก DataFrame ของคุณมี MultiIndex:
หากคุณมี DataFrame multiindex to_dict
ก่อนอื่นคุณต้องตั้งค่าก่อนที่จะเรียก จากนั้นคุณต้องสร้างดัชนีใหม่โดยใช้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
นี่คือเวอร์ชันdput
- เครื่องมือ R มาตรฐานของฉันในการสร้างรายงานที่ทำซ้ำได้ - สำหรับ Pandas DataFrame
s อาจจะล้มเหลวสำหรับเฟรมที่ซับซ้อนมากขึ้น แต่ดูเหมือนว่าจะทำงานได้ดีในกรณีง่ายๆ:
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)
ตอนนี้
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)))
โปรดทราบว่าสิ่งนี้ให้ผลลัพธ์ที่ละเอียดกว่าDataFrame.to_dict
มากเช่น
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))
เทียบกับ
{'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}}
สำหรับdu
ด้านบน แต่จะรักษาประเภทคอลัมน์ไว้ เช่นในกรณีทดสอบข้างต้น
du.equals(pd.DataFrame(du.to_dict()))
==> False
เพราะdu.dtypes
เป็นuint8
และเป็นpd.DataFrame(du.to_dict()).dtypes
int64