Python pandas: เก็บคอลัมน์ที่เลือกไว้เป็น DataFrame แทน Series


92

เมื่อเลือกคอลัมน์เดียวจากหมีแพนด้า DataFrame (พูดdf.iloc[:, 0], df['A']หรือdf.Aฯลฯ ) เวกเตอร์ส่งผลให้ถูกแปลงโดยอัตโนมัติเพื่อให้ซีรีส์แทน DataFrame คอลัมน์เดียว อย่างไรก็ตามฉันกำลังเขียนฟังก์ชันบางอย่างที่ใช้ DataFrame เป็นอาร์กิวเมนต์อินพุต ดังนั้นฉันชอบจัดการกับ DataFrame แบบคอลัมน์เดียวแทนที่จะเป็นซีรี่ส์เพื่อให้ฟังก์ชันสามารถสมมติว่าสามารถเข้าถึง df.columns ได้ ตอนนี้ผมต้องชัดเจนแปลงชุดเข้า DataFrame pd.DataFrame(df.iloc[:, 0])โดยใช้สิ่งที่ต้องการ นี่ดูเหมือนจะไม่ใช่วิธีที่สะอาดที่สุด มีวิธีที่สวยงามกว่าในการจัดทำดัชนีจาก DataFrame โดยตรงเพื่อให้ผลลัพธ์เป็น DataFrame แบบคอลัมน์เดียวแทนที่จะเป็น Series หรือไม่?


6
df.iloc [:, [0]] หรือ df [['A']]; df.A เท่านั้นที่จะคืนชุด
เจฟฟ์

คำตอบ:


99

ดังที่ @Jeff กล่าวถึงมีสองสามวิธีในการดำเนินการนี้ แต่ฉันขอแนะนำให้ใช้ loc / iloc เพื่อให้ชัดเจนยิ่งขึ้น (และเพิ่มข้อผิดพลาดในช่วงต้นหากคุณพยายามทำสิ่งที่ไม่ชัดเจน)

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

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

In [12]: df[['A']]

In [13]: df[[0]]

In [14]: df.loc[:, ['A']]

In [15]: df.iloc[:, [0]]

Out[12-15]:  # they all return the same thing:
   A
0  1
1  3

สองตัวเลือกหลังจะลบความคลุมเครือในกรณีของชื่อคอลัมน์จำนวนเต็ม (เหตุใดจึงสร้าง loc / iloc) ตัวอย่างเช่น:

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

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

In [18]: df[[0]]  # ambiguous
Out[18]:
   A
0  1
1  3

2
ขออภัยที่รบกวนคุณ แต่เป็นเพียงคำถามสั้น ๆ เกี่ยวกับเรื่องนี้ ฉันเห็นว่าส่วนพิเศษ[]ทำให้ผลลัพธ์เป็นDataFrameแทนที่จะเป็น a ได้Seriesอย่างไร แต่ในเอกสารแพนด้ามีการกล่าวถึงไวยากรณ์การจัดทำดัชนีประเภทนี้ที่ไหน ฉันแค่พยายามหาชื่อ "อย่างเป็นทางการ" สำหรับเทคนิคการจัดทำดัชนีนี้เพื่อที่ฉันจะได้เข้าใจมันจริงๆ ขอบคุณ!
sparc_spread

3
@sparc_spread pandas.pydata.org/pandas-docs/stable/indexing.html#basics "คุณสามารถส่งรายการคอลัมน์ไปที่ [] เพื่อเลือกคอลัมน์ตามลำดับนั้น" ฉันไม่แน่ใจว่านี่มีชื่อ!
Andy Hayden

ใช่ดูเหมือนว่าจะไม่มี - แต่ฉันจะใช้ต่อจากนี้ น่าทึ่งมากที่สิ่งต่างๆถูกฝังอยู่ในทั้ง API และเอกสาร ขอบคุณ!
sparc_spread

ความแตกต่างนี้มีประโยชน์สำหรับฉันเพราะบางครั้งฉันต้องการ DataFrame แบบคอลัมน์เดียวดังนั้นฉันจึงสามารถใช้เมธอด DataFrame กับข้อมูลที่ไม่มีในซีรี่ส์ได้ (ISTR วิธีการพล็อตทำงานแตกต่างกัน) มันเป็นความศักดิ์สิทธิ์สำหรับฉันเมื่อฉันรู้ว่าฉันสามารถใช้รายการองค์ประกอบเดียวได้!
RufusVS

4

ตามที่Andy Haydenแนะนำการใช้. iloc / .loc เพื่อสร้างดัชนีดาต้าเฟรม (คอลัมน์เดียว) เป็นวิธีที่จะไป จุดที่ควรทราบอีกประการหนึ่งคือการแสดงตำแหน่งดัชนี ใช้ป้าย / ตำแหน่งดัชนีในรายการในขณะที่ระบุค่าอาร์กิวเมนต์เพื่อจัดทำดัชนีเป็น Dataframe หากทำไม่สำเร็จจะส่งคืน 'pandas.core.series.Series'

อินพุต:

    A_1 = train_data.loc[:,'Fraudster']
    print('A_1 is of type', type(A_1))
    A_2 = train_data.loc[:, ['Fraudster']]
    print('A_2 is of type', type(A_2))
    A_3 = train_data.iloc[:,12]
    print('A_3 is of type', type(A_3))
    A_4 = train_data.iloc[:,[12]]
    print('A_4 is of type', type(A_4))

เอาท์พุต:

    A_1 is of type <class 'pandas.core.series.Series'>
    A_2 is of type <class 'pandas.core.frame.DataFrame'>
    A_3 is of type <class 'pandas.core.series.Series'>
    A_4 is of type <class 'pandas.core.frame.DataFrame'>

1

คุณสามารถใช้ได้df.iloc[:, 0:1]ในกรณีนี้เวกเตอร์ที่ได้จะเป็นDataFrameและไม่ใช่อนุกรม

อย่างที่เห็น:

ป้อนคำอธิบายภาพที่นี่


1

มีการกล่าวถึงสามแนวทางนี้:

pd.DataFrame(df.loc[:, 'A'])  # Approach of the original post
df.loc[:,[['A']]              # Approach 2 (note: use iloc for positional indexing)
df[['A']]                     # Approach 3

pd.Series.to_frame () เป็นอีกแนวทางหนึ่ง

เนื่องจากเป็นวิธีการจึงสามารถใช้ในสถานการณ์ที่ไม่สามารถใช้แนวทางที่สองและสามข้างต้นได้ โดยเฉพาะอย่างยิ่งจะมีประโยชน์เมื่อใช้วิธีการบางอย่างกับคอลัมน์ในดาต้าเฟรมของคุณและคุณต้องการแปลงเอาต์พุตเป็นดาต้าเฟรมแทนที่จะเป็นอนุกรม ตัวอย่างเช่นใน Jupyter Notebook ซีรีส์จะไม่มีเอาต์พุตสวย ๆ แต่ดาต้าเฟรมจะ

# Basic use case: 
df['A'].to_frame()

# Use case 2 (this will give you pretty output in a Jupyter Notebook): 
df['A'].describe().to_frame()

# Use case 3: 
df['A'].str.strip().to_frame()

# Use case 4: 
def some_function(num): 
    ...

df['A'].apply(some_function).to_frame()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.