วิธีการหมุนกรอบข้อมูล?
- Pivot คืออะไร?
- ฉันจะหมุนได้อย่างไร
- นี่คือเดือย?
- รูปแบบยาวไปจนถึงรูปแบบกว้าง?
ฉันเคยเห็นคำถามมากมายที่ถามเกี่ยวกับตารางเดือย แม้ว่าพวกเขาจะไม่รู้ว่าพวกเขากำลังถามเกี่ยวกับตาราง Pivot แต่ก็มักจะเป็นเช่นนั้น แทบจะเป็นไปไม่ได้เลยที่จะเขียนคำถามและคำตอบที่เป็นที่ยอมรับซึ่งครอบคลุมทุกแง่มุมของการหมุน ...
... แต่ฉันจะปล่อยมันไป
ปัญหาเกี่ยวกับคำถามและคำตอบที่มีอยู่คือบ่อยครั้งที่คำถามมุ่งเน้นไปที่ความแตกต่างเล็กน้อยที่ OP มีปัญหาในการสรุปเพื่อใช้คำตอบที่ดีที่มีอยู่จำนวนหนึ่ง อย่างไรก็ตามไม่มีคำตอบใดที่พยายามให้คำอธิบายที่ครอบคลุม (เนื่องจากเป็นงานที่น่ากลัว)
ดูตัวอย่างบางส่วนจากการค้นหาโดย Googleของฉัน
- คำถามและคำตอบที่ดี แต่คำตอบจะตอบเฉพาะคำถามที่เจาะจงโดยมีคำอธิบายเพียงเล็กน้อย
- ในคำถามนี้ OP เกี่ยวข้องกับเอาต์พุตของเดือย ได้แก่ ลักษณะของคอลัมน์ OP ต้องการให้ดูเหมือน R สิ่งนี้ไม่เป็นประโยชน์สำหรับผู้ใช้แพนด้า
- อีกคำถามที่ดี แต่คำตอบมุ่งเน้นไปที่วิธีการเดียวคือ
pd.DataFrame.pivot
ดังนั้นเมื่อใดก็ตามที่มีคนค้นหาpivot
พวกเขาจะได้รับผลลัพธ์เป็นระยะ ๆ ซึ่งมีแนวโน้มว่าจะไม่ตอบคำถามเฉพาะของพวกเขา
ติดตั้ง
คุณอาจสังเกตเห็นว่าฉันตั้งชื่อคอลัมน์และค่าคอลัมน์ที่เกี่ยวข้องอย่างชัดเจนเพื่อให้สอดคล้องกับวิธีที่ฉันจะหมุนในคำตอบด้านล่าง
import numpy as np
import pandas as pd
from numpy.core.defchararray import add
np.random.seed([3,1415])
n = 20
cols = np.array(['key', 'row', 'item', 'col'])
arr1 = (np.random.randint(5, size=(n, 4)) // [2, 1, 2, 1]).astype(str)
df = pd.DataFrame(
add(cols, arr1), columns=cols
).join(
pd.DataFrame(np.random.rand(n, 2).round(2)).add_prefix('val')
)
print(df)
key row item col val0 val1
0 key0 row3 item1 col3 0.81 0.04
1 key1 row2 item1 col2 0.44 0.07
2 key1 row0 item1 col0 0.77 0.01
3 key0 row4 item0 col2 0.15 0.59
4 key1 row0 item2 col1 0.81 0.64
5 key1 row2 item2 col4 0.13 0.88
6 key2 row4 item1 col3 0.88 0.39
7 key1 row4 item1 col1 0.10 0.07
8 key1 row0 item2 col4 0.65 0.02
9 key1 row2 item0 col2 0.35 0.61
10 key2 row0 item2 col1 0.40 0.85
11 key2 row4 item1 col2 0.64 0.25
12 key0 row2 item2 col3 0.50 0.44
13 key0 row4 item1 col4 0.24 0.46
14 key1 row3 item2 col3 0.28 0.11
15 key0 row3 item1 col1 0.31 0.23
16 key0 row0 item2 col3 0.86 0.01
17 key0 row4 item0 col3 0.64 0.21
18 key2 row2 item2 col0 0.13 0.45
19 key0 row2 item0 col4 0.37 0.70
คำถาม
ทำไมฉันถึงได้รับ
ValueError: Index contains duplicate entries, cannot reshape
ฉันจะหมุน
df
เพื่อให้col
ค่าเป็นคอลัมน์row
ค่าเป็นดัชนีและค่าเฉลี่ยของval0
ค่าได้อย่างไรcol col0 col1 col2 col3 col4 row row0 0.77 0.605 NaN 0.860 0.65 row2 0.13 NaN 0.395 0.500 0.25 row3 NaN 0.310 NaN 0.545 NaN row4 NaN 0.100 0.395 0.760 0.24
ฉันจะหมุน
df
เพื่อให้col
ค่าเป็นคอลัมน์row
ค่าเป็นดัชนีค่าเฉลี่ยของval0
ค่าและค่าที่ขาดหายไปได้0
อย่างไรcol col0 col1 col2 col3 col4 row row0 0.77 0.605 0.000 0.860 0.65 row2 0.13 0.000 0.395 0.500 0.25 row3 0.00 0.310 0.000 0.545 0.00 row4 0.00 0.100 0.395 0.760 0.24
ฉันจะได้รับสิ่งอื่นที่ไม่ใช่
mean
เช่นอาจจะsum
?col col0 col1 col2 col3 col4 row row0 0.77 1.21 0.00 0.86 0.65 row2 0.13 0.00 0.79 0.50 0.50 row3 0.00 0.31 0.00 1.09 0.00 row4 0.00 0.10 0.79 1.52 0.24
ฉันสามารถทำการรวมครั้งละมากขึ้นได้หรือไม่
sum mean col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4 row row0 0.77 1.21 0.00 0.86 0.65 0.77 0.605 0.000 0.860 0.65 row2 0.13 0.00 0.79 0.50 0.50 0.13 0.000 0.395 0.500 0.25 row3 0.00 0.31 0.00 1.09 0.00 0.00 0.310 0.000 0.545 0.00 row4 0.00 0.10 0.79 1.52 0.24 0.00 0.100 0.395 0.760 0.24
ฉันสามารถรวมคอลัมน์หลายค่าได้หรือไม่
val0 val1 col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4 row row0 0.77 0.605 0.000 0.860 0.65 0.01 0.745 0.00 0.010 0.02 row2 0.13 0.000 0.395 0.500 0.25 0.45 0.000 0.34 0.440 0.79 row3 0.00 0.310 0.000 0.545 0.00 0.00 0.230 0.00 0.075 0.00 row4 0.00 0.100 0.395 0.760 0.24 0.00 0.070 0.42 0.300 0.46
สามารถแบ่งย่อยตามหลายคอลัมน์ได้หรือไม่?
item item0 item1 item2 col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4 row row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.605 0.86 0.65 row2 0.35 0.00 0.37 0.00 0.00 0.44 0.00 0.00 0.13 0.000 0.50 0.13 row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.000 0.28 0.00 row4 0.15 0.64 0.00 0.00 0.10 0.64 0.88 0.24 0.00 0.000 0.00 0.00
หรือ
item item0 item1 item2 col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4 key row key0 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.86 0.00 row2 0.00 0.00 0.37 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.50 0.00 row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.00 0.00 0.00 row4 0.15 0.64 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 0.00 0.00 key1 row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.81 0.00 0.65 row2 0.35 0.00 0.00 0.00 0.00 0.44 0.00 0.00 0.00 0.00 0.00 0.13 row3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.00 row4 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 key2 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.40 0.00 0.00 row2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 0.00 0.00 row4 0.00 0.00 0.00 0.00 0.00 0.64 0.88 0.00 0.00 0.00 0.00 0.00
ฉันสามารถรวมความถี่ที่คอลัมน์และแถวเกิดขึ้นพร้อมกันหรือที่เรียกว่า "cross tabulation" ได้หรือไม่
col col0 col1 col2 col3 col4 row row0 1 2 0 1 1 row2 1 0 2 1 2 row3 0 1 0 2 0 row4 0 1 2 2 1
ฉันจะแปลง DataFrame จากแบบยาวเป็นแบบกว้างโดยการหมุนเฉพาะสองคอลัมน์ได้อย่างไร ให้
np.random.seed([3, 1415]) df2 = pd.DataFrame({'A': list('aaaabbbc'), 'B': np.random.choice(15, 8)}) df2 A B 0 a 0 1 a 11 2 a 2 3 a 11 4 b 10 5 b 10 6 b 14 7 c 7
สิ่งที่คาดหวังควรมีลักษณะดังนี้
a b c 0 0.0 10.0 7.0 1 11.0 10.0 NaN 2 2.0 14.0 NaN 3 11.0 NaN NaN
ฉันจะแบนดัชนีหลายดัชนีให้เป็นดัชนีเดียวได้อย่างไร
pivot
จาก
1 2 1 1 2 a 2 1 1 b 2 1 0 c 1 0 0
ถึง
1|1 2|1 2|2 a 2 1 1 b 2 1 0 c 1 0 0
คำตอบ
เราเริ่มต้นด้วยการตอบคำถามแรก:
คำถามที่ 1
ทำไมฉันถึงได้รับ
ValueError: Index contains duplicate entries, cannot reshape
สิ่งนี้เกิดขึ้นเนื่องจากแพนด้าพยายามที่จะทำดัชนีอีกครั้งไม่ว่าจะเป็นวัตถุcolumns
หรือindex
วัตถุที่มีรายการซ้ำกัน มีวิธีการใช้งานที่แตกต่างกันซึ่งสามารถหมุนได้ บางปุ่มไม่เหมาะอย่างยิ่งเมื่อมีคีย์ที่ซ้ำกันซึ่งจะถูกขอให้หมุน ตัวอย่างเช่น. พิจารณาpd.DataFrame.pivot
. ฉันรู้ว่ามีรายการซ้ำกันที่แชร์ค่าrow
และcol
:
df.duplicated(['row', 'col']).any()
True
ดังนั้นเมื่อฉันpivot
ใช้
df.pivot(index='row', columns='col', values='val0')
ฉันได้รับข้อผิดพลาดดังกล่าวข้างต้น อันที่จริงฉันได้รับข้อผิดพลาดเดียวกันเมื่อพยายามทำงานเดียวกันกับ:
df.set_index(['row', 'col'])['val0'].unstack()
นี่คือรายการสำนวนที่เราสามารถใช้เพื่อเดือยได้
pd.DataFrame.groupby
+pd.DataFrame.unstack
- แนวทางทั่วไปที่ดีสำหรับการทำเดือยทุกประเภท
- คุณระบุคอลัมน์ทั้งหมดที่จะประกอบเป็นระดับแถวและระดับคอลัมน์ที่หมุนอยู่ในกลุ่มเดียวโดย คุณทำตามนั้นโดยการเลือกคอลัมน์ที่เหลือที่คุณต้องการรวมและฟังก์ชันที่คุณต้องการทำการรวม สุดท้ายคุณ
unstack
คือระดับที่คุณต้องการให้อยู่ในดัชนีคอลัมน์
pd.DataFrame.pivot_table
- เวอร์ชันที่ได้รับการยกย่อง
groupby
พร้อม API ที่ใช้งานง่ายยิ่งขึ้น สำหรับหลาย ๆ คนนี่คือแนวทางที่ต้องการ และเป็นแนวทางที่นักพัฒนาต้องการ - ระบุระดับแถวระดับคอลัมน์ค่าที่จะรวมและฟังก์ชันที่จะทำการรวม
- เวอร์ชันที่ได้รับการยกย่อง
pd.DataFrame.set_index
+pd.DataFrame.unstack
- สะดวกและใช้งานง่ายสำหรับบางคน (รวมตัวเอง) ไม่สามารถจัดการคีย์ที่จัดกลุ่มซ้ำกัน
- เช่นเดียวกับ
groupby
กระบวนทัศน์เราระบุคอลัมน์ทั้งหมดซึ่งสุดท้ายแล้วจะเป็นระดับแถวหรือคอลัมน์และกำหนดให้เป็นดัชนี จากนั้นเราจะได้unstack
ระดับที่เราต้องการในคอลัมน์ หากระดับดัชนีหรือระดับคอลัมน์ที่เหลือไม่ซ้ำกันวิธีนี้จะล้มเหลว
pd.DataFrame.pivot
- คล้ายกันมากกับการ
set_index
แบ่งปันข้อ จำกัด ของคีย์ที่ซ้ำกัน API ก็มี จำกัด เช่นกัน มันใช้เวลาเพียงค่าสเกลาสำหรับindex
, ,columns
values
- คล้ายกับ
pivot_table
วิธีการที่เราเลือกแถวคอลัมน์และค่าที่จะหมุน อย่างไรก็ตามเราไม่สามารถรวมได้และหากแถวหรือคอลัมน์ไม่ซ้ำกันวิธีนี้จะล้มเหลว
- คล้ายกันมากกับการ
pd.crosstab
- เวอร์ชันพิเศษ
pivot_table
และในรูปแบบที่บริสุทธิ์ที่สุดนี้เป็นวิธีที่ใช้งานง่ายที่สุดในการทำงานหลายอย่าง
- เวอร์ชันพิเศษ
pd.factorize
+np.bincount
- นี่เป็นเทคนิคขั้นสูงที่คลุมเครือ แต่รวดเร็วมาก ไม่สามารถใช้ได้ในทุกสถานการณ์ แต่เมื่อสามารถใช้ได้และคุณสบายใจที่จะใช้งานคุณจะได้รับผลตอบแทนจากการปฏิบัติงาน
pd.get_dummies
+pd.DataFrame.dot
- ฉันใช้สิ่งนี้เพื่อดำเนินการข้ามตารางอย่างชาญฉลาด
ตัวอย่าง
pd.DataFrame.pivot_table
สิ่งที่ฉันจะทำสำหรับแต่ละคำตอบที่ตามมาและเป็นคำถามที่จะตอบได้โดยใช้ จากนั้นฉันจะให้ทางเลือกอื่นในการทำงานเดียวกัน
คำถาม 3
ฉันจะหมุน
df
เพื่อให้col
ค่าเป็นคอลัมน์row
ค่าเป็นดัชนีค่าเฉลี่ยของval0
ค่าและค่าที่ขาดหายไปได้0
อย่างไร
pd.DataFrame.pivot_table
fill_value
ไม่ได้ตั้งค่าตามค่าเริ่มต้น ฉันมักจะตั้งค่าให้เหมาะสม0
ในกรณีนี้ผมตั้งค่าให้ สังเกตว่าฉันข้ามคำถาม 2เพราะเหมือนกับคำตอบนี้โดยไม่มีfill_value
aggfunc='mean'
เป็นค่าเริ่มต้นและฉันไม่ต้องตั้งค่า ฉันรวมไว้ให้ชัดเจนdf.pivot_table( values='val0', index='row', columns='col', fill_value=0, aggfunc='mean') col col0 col1 col2 col3 col4 row row0 0.77 0.605 0.000 0.860 0.65 row2 0.13 0.000 0.395 0.500 0.25 row3 0.00 0.310 0.000 0.545 0.00 row4 0.00 0.100 0.395 0.760 0.24
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].mean().unstack(fill_value=0)
pd.crosstab
pd.crosstab( index=df['row'], columns=df['col'], values=df['val0'], aggfunc='mean').fillna(0)
คำถาม 4
ฉันจะได้รับสิ่งอื่นที่ไม่ใช่
mean
เช่นอาจจะsum
?
pd.DataFrame.pivot_table
df.pivot_table( values='val0', index='row', columns='col', fill_value=0, aggfunc='sum') col col0 col1 col2 col3 col4 row row0 0.77 1.21 0.00 0.86 0.65 row2 0.13 0.00 0.79 0.50 0.50 row3 0.00 0.31 0.00 1.09 0.00 row4 0.00 0.10 0.79 1.52 0.24
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].sum().unstack(fill_value=0)
pd.crosstab
pd.crosstab( index=df['row'], columns=df['col'], values=df['val0'], aggfunc='sum').fillna(0)
คำถาม 5
ฉันสามารถทำการรวมครั้งละมากขึ้นได้หรือไม่
สังเกตว่าสำหรับpivot_table
และcrosstab
ฉันจำเป็นต้องส่งผ่านรายการ callables ในทางกลับกันgroupby.agg
สามารถใช้สตริงสำหรับฟังก์ชันพิเศษจำนวน จำกัด groupby.agg
ก็จะนำคำเรียกเดียวกันที่เราส่งต่อไปให้คนอื่น ๆ แต่มักจะมีประสิทธิภาพมากกว่าในการใช้ประโยชน์จากชื่อฟังก์ชันสตริงเนื่องจากมีประสิทธิภาพที่จะได้รับ
pd.DataFrame.pivot_table
df.pivot_table( values='val0', index='row', columns='col', fill_value=0, aggfunc=[np.size, np.mean]) size mean col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4 row row0 1 2 0 1 1 0.77 0.605 0.000 0.860 0.65 row2 1 0 2 1 2 0.13 0.000 0.395 0.500 0.25 row3 0 1 0 2 0 0.00 0.310 0.000 0.545 0.00 row4 0 1 2 2 1 0.00 0.100 0.395 0.760 0.24
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].agg(['size', 'mean']).unstack(fill_value=0)
pd.crosstab
pd.crosstab( index=df['row'], columns=df['col'], values=df['val0'], aggfunc=[np.size, np.mean]).fillna(0, downcast='infer')
คำถามที่ 6
ฉันสามารถรวมคอลัมน์หลายค่าได้หรือไม่
pd.DataFrame.pivot_table
เราผ่านไปได้values=['val0', 'val1']
แต่เราสามารถทิ้งสิ่งนั้นได้อย่างสมบูรณ์df.pivot_table( values=['val0', 'val1'], index='row', columns='col', fill_value=0, aggfunc='mean') val0 val1 col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4 row row0 0.77 0.605 0.000 0.860 0.65 0.01 0.745 0.00 0.010 0.02 row2 0.13 0.000 0.395 0.500 0.25 0.45 0.000 0.34 0.440 0.79 row3 0.00 0.310 0.000 0.545 0.00 0.00 0.230 0.00 0.075 0.00 row4 0.00 0.100 0.395 0.760 0.24 0.00 0.070 0.42 0.300 0.46
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0', 'val1'].mean().unstack(fill_value=0)
คำถาม 7
สามารถแบ่งย่อยตามหลายคอลัมน์ได้หรือไม่?
pd.DataFrame.pivot_table
df.pivot_table( values='val0', index='row', columns=['item', 'col'], fill_value=0, aggfunc='mean') item item0 item1 item2 col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4 row row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.605 0.86 0.65 row2 0.35 0.00 0.37 0.00 0.00 0.44 0.00 0.00 0.13 0.000 0.50 0.13 row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.000 0.28 0.00 row4 0.15 0.64 0.00 0.00 0.10 0.64 0.88 0.24 0.00 0.000 0.00 0.00
pd.DataFrame.groupby
df.groupby( ['row', 'item', 'col'] )['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
คำถามที่ 8
สามารถแบ่งย่อยตามหลายคอลัมน์ได้หรือไม่?
pd.DataFrame.pivot_table
df.pivot_table( values='val0', index=['key', 'row'], columns=['item', 'col'], fill_value=0, aggfunc='mean') item item0 item1 item2 col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4 key row key0 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.86 0.00 row2 0.00 0.00 0.37 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.50 0.00 row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.00 0.00 0.00 row4 0.15 0.64 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 0.00 0.00 key1 row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.81 0.00 0.65 row2 0.35 0.00 0.00 0.00 0.00 0.44 0.00 0.00 0.00 0.00 0.00 0.13 row3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.00 row4 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 key2 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.40 0.00 0.00 row2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 0.00 0.00 row4 0.00 0.00 0.00 0.00 0.00 0.64 0.88 0.00 0.00 0.00 0.00 0.00
pd.DataFrame.groupby
df.groupby( ['key', 'row', 'item', 'col'] )['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
pd.DataFrame.set_index
เนื่องจากชุดคีย์ไม่ซ้ำกันสำหรับทั้งแถวและคอลัมน์df.set_index( ['key', 'row', 'item', 'col'] )['val0'].unstack(['item', 'col']).fillna(0).sort_index(1)
คำถามที่ 9
ฉันสามารถรวมความถี่ที่คอลัมน์และแถวเกิดขึ้นพร้อมกันหรือที่เรียกว่า "cross tabulation" ได้หรือไม่
pd.DataFrame.pivot_table
df.pivot_table(index='row', columns='col', fill_value=0, aggfunc='size') col col0 col1 col2 col3 col4 row row0 1 2 0 1 1 row2 1 0 2 1 2 row3 0 1 0 2 0 row4 0 1 2 2 1
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].size().unstack(fill_value=0)
pd.crosstab
pd.crosstab(df['row'], df['col'])
pd.factorize
+np.bincount
# get integer factorization `i` and unique values `r` # for column `'row'` i, r = pd.factorize(df['row'].values) # get integer factorization `j` and unique values `c` # for column `'col'` j, c = pd.factorize(df['col'].values) # `n` will be the number of rows # `m` will be the number of columns n, m = r.size, c.size # `i * m + j` is a clever way of counting the # factorization bins assuming a flat array of length # `n * m`. Which is why we subsequently reshape as `(n, m)` b = np.bincount(i * m + j, minlength=n * m).reshape(n, m) # BTW, whenever I read this, I think 'Bean, Rice, and Cheese' pd.DataFrame(b, r, c) col3 col2 col0 col1 col4 row3 2 0 0 1 0 row2 1 2 1 0 2 row0 1 0 1 2 1 row4 2 2 0 1 1
pd.get_dummies
pd.get_dummies(df['row']).T.dot(pd.get_dummies(df['col'])) col0 col1 col2 col3 col4 row0 1 2 0 1 1 row2 1 0 2 1 2 row3 0 1 0 2 0 row4 0 1 2 2 1
คำถามที่ 10
ฉันจะแปลง DataFrame จากแบบยาวเป็นแบบกว้างโดยการหมุนเฉพาะสองคอลัมน์ได้อย่างไร
ขั้นตอนแรกคือการกำหนดตัวเลขให้กับแต่ละแถว - ตัวเลขนี้จะเป็นดัชนีแถวของค่านั้นในผลลัพธ์ที่หมุน ทำได้โดยใช้GroupBy.cumcount
:
df2.insert(0, 'count', df.groupby('A').cumcount())
df2
count A B
0 0 a 0
1 1 a 11
2 2 a 2
3 3 a 11
4 0 b 10
5 1 b 10
6 2 b 14
7 0 c 7
DataFrame.pivot
ขั้นตอนที่สองคือการใช้คอลัมน์ที่สร้างขึ้นใหม่เป็นดัชนีที่จะเรียก
df2.pivot(*df)
# df.pivot(index='count', columns='A', values='B')
A a b c
count
0 0.0 10.0 7.0
1 11.0 10.0 NaN
2 2.0 14.0 NaN
3 11.0 NaN NaN
คำถาม 11
ฉันจะแบนดัชนีหลายดัชนีให้เป็นดัชนีเดียวได้อย่างไร
pivot
ถ้าcolumns
พิมพ์object
ด้วยสตริงjoin
df.columns = df.columns.map('|'.join)
อื่น format
df.columns = df.columns.map('{0[0]}|{0[1]}'.format)
หากต้องการขยายคำตอบของ @ piRSquaredอีกรุ่นของคำถามที่ 10
คำถามที่ 10.1
DataFrame:
d = data = {'A': {0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 3, 6: 5},
'B': {0: 'a', 1: 'b', 2: 'c', 3: 'a', 4: 'b', 5: 'a', 6: 'c'}}
df = pd.DataFrame(d)
A B
0 1 a
1 1 b
2 1 c
3 2 a
4 2 b
5 3 a
6 5 c
เอาท์พุต:
0 1 2
A
1 a b c
2 a b None
3 a None None
5 c None None
การใช้df.groupby
และpd.Series.tolist
t = df.groupby('A')['B'].apply(list)
out = pd.DataFrame(t.tolist(),index=t.index)
out
0 1 2
A
1 a b c
2 a b None
3 a None None
5 c None None
หรือทางเลือกที่ดีกว่ามากโดยใช้pd.pivot_table
กับdf.squeeze.
t = df.pivot_table(index='A',values='B',aggfunc=list).squeeze()
out = pd.DataFrame(t.tolist(),index=t.index)