แทรกแถวเพื่อแพนด้าดาต้าเฟรม


112

ฉันมีดาต้าเฟรม:

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

   A  B  C
0  5  6  7
1  7  8  9

[2 rows x 3 columns]

และฉันต้องเพิ่มแถวแรก [2, 3, 4] เพื่อรับ:

   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

ฉันได้ลองappend()และconcat()ใช้งานแล้ว แต่ไม่พบวิธีการที่ถูกต้อง

จะเพิ่ม / แทรกซีรีส์ในดาต้าเฟรมได้อย่างไร?


6
ทราบว่ามันจะดีกว่าที่จะใช้s1.valuesเมื่อเทียบกับการที่คุณจะสร้างรายการใหม่ทั้งหมดโดยใช้list(s1) list(s1)
acushner

7
ฉันไม่เข้าใจว่าทำไมทุกคนถึงชอบแพนด้ามากในเมื่อสิ่งที่ควรจะเรียบง่ายเช่นนั้นคือความเจ็บปวดที่ตูดและช้ามาก
MattCochrane

คำตอบ:


145

เพียงกำหนดแถวให้กับดัชนีเฉพาะโดยใช้loc:

 df.loc[-1] = [2, 3, 4]  # adding a row
 df.index = df.index + 1  # shifting index
 df = df.sort_index()  # sorting by index

และคุณจะได้รับตามที่ต้องการ:

    A  B  C
 0  2  3  4
 1  5  6  7
 2  7  8  9

ดูในนุ่นเอกสารการจัดทำดัชนี: การตั้งค่าที่มีการขยายตัว


2
หากคุณไม่ต้องการตั้งค่าด้วยการขยาย แต่ใส่เข้าไปใน dataframe ลองดูที่stackoverflow.com/questions/15888648/…
FooBar

6
ทางเลือกดัชนีการขยับ: df.sort (). reset_index (drop = True)
Meloun

2
df.sort เลิกใช้แล้วใช้ df.sort_index ()
GBGOLC

1
@Piotr - ใช้งานได้ดี แต่จะเกิดอะไรขึ้นเมื่อคุณต้องการทำซ้ำแถวจาก data frame ของคุณเช่นdf.loc[-1] = df.iloc[[0]]และแทรกสิ่งนั้น เฟรมมาพร้อมกับคอลัมน์ดัชนีที่เพิ่มเข้ามาซึ่งทำให้เกิดข้อผิดพลาดValueError: cannot set a row with mismatched columns (ดูstackoverflow.com/questions/47340571/… )
Growler

5
ฉันคิดว่าdf.loc[-1] = [2, 3, 4] # adding a rowมันทำให้เข้าใจผิดเล็กน้อยเนื่องจาก-1ไม่ใช่แถว / องค์ประกอบสุดท้ายเนื่องจากเป็นอาร์เรย์ Python
flow2k

27

ไม่แน่ใจว่าคุณเรียกใช้อย่างไรconcat()แต่ควรใช้งานได้ตราบเท่าที่วัตถุทั้งสองเป็นประเภทเดียวกัน บางทีปัญหาคือคุณต้องส่งเวกเตอร์ที่สองของคุณไปยังดาต้าเฟรมหรือไม่ การใช้ df ที่คุณกำหนดไว้ต่อไปนี้ใช้ได้กับฉัน:

df2 = pd.DataFrame([[2,3,4]], columns=['A','B','C'])
pd.concat([df2, df])

คำตอบที่ดีที่สุด ^ :)
Cam.Davidson.Pilon

23

วิธีหนึ่งในการบรรลุเป้าหมายนี้คือ

>>> pd.DataFrame(np.array([[2, 3, 4]]), columns=['A', 'B', 'C']).append(df, ignore_index=True)
Out[330]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

โดยทั่วไปการต่อท้ายดาต้าเฟรมไม่ใช่ซีรีส์จะง่ายที่สุด ในกรณีของคุณเนื่องจากคุณต้องการให้แถวใหม่เป็น "ด้านบน" (ด้วย id เริ่มต้น) และไม่มีฟังก์ชันใดpd.prepend()ๆ ฉันต้องสร้าง dataframe ใหม่ก่อนแล้วจึงต่อท้ายอันเก่าของคุณ

ignore_indexจะไม่สนใจอย่างต่อเนื่องดัชนีเก่า dataframe ของคุณและให้แน่ใจว่าแถวแรกจริงเริ่มต้นด้วยดัชนีแทนการเริ่มต้นใหม่ที่มีค่าดัชนี10

คำเตือนทั่วไป: Cetero censeo ... การต่อท้ายแถวเป็นการดำเนินการที่ค่อนข้างไม่มีประสิทธิภาพ หากคุณสนใจเกี่ยวกับประสิทธิภาพและสามารถตรวจสอบให้แน่ใจก่อนสร้าง dataframe ด้วยดัชนีที่ถูกต้อง (ยาวกว่า) จากนั้นเพียงแค่ใส่แถวเพิ่มเติมลงใน dataframe คุณควรทำเช่นนั้นอย่างแน่นอน ดู:

>>> index = np.array([0, 1, 2])
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[0:1] = [list(s1), list(s2)]
>>> df2
Out[336]: 
     A    B    C
0    5    6    7
1    7    8    9
2  NaN  NaN  NaN
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[1:] = [list(s1), list(s2)]

จนถึงตอนนี้เรามีสิ่งที่คุณมีdfดังนี้:

>>> df2
Out[339]: 
     A    B    C
0  NaN  NaN  NaN
1    5    6    7
2    7    8    9

แต่ตอนนี้คุณสามารถแทรกแถวได้ง่ายๆดังนี้ เนื่องจากมีการจัดสรรพื้นที่ล่วงหน้าจึงมีประสิทธิภาพมากขึ้น

>>> df2.loc[0] = np.array([2, 3, 4])
>>> df2
Out[341]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

นั่นเป็นวิธีแก้ปัญหาที่ดีฉันพยายามแทรกซีรีส์ลงในดาต้าเฟรม มันดีพอสำหรับฉันในตอนนี้
Meloun

ฉันชอบตัวเลือกสุดท้ายมากที่สุด สิ่งนี้ตรงกับสิ่งที่ฉันอยากทำจริงๆ ขอบคุณ @FooBar!
Jade Cacho

13

ฉันรวบรวมฟังก์ชันสั้น ๆ ที่ช่วยให้มีความยืดหยุ่นมากขึ้นเล็กน้อยเมื่อแทรกแถว:

def insert_row(idx, df, df_insert):
    dfA = df.iloc[:idx, ]
    dfB = df.iloc[idx:, ]

    df = dfA.append(df_insert).append(dfB).reset_index(drop = True)

    return df

ซึ่งสามารถย่อให้สั้นลงเป็น:

def insert_row(idx, df, df_insert):
    return df.iloc[:idx, ].append(df_insert).append(df.iloc[idx:, ]).reset_index(drop = True)

จากนั้นคุณสามารถใช้สิ่งต่างๆเช่น:

df = insert_row(2, df, df_new)

ซึ่ง2เป็นตำแหน่งดัชนีในที่ที่คุณต้องการแทรกdfdf_new


7

เราสามารถใช้numpy.insert. สิ่งนี้มีข้อดีคือความยืดหยุ่น คุณจะต้องระบุดัชนีที่คุณต้องการแทรกเท่านั้น

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

pd.DataFrame(np.insert(df.values, 0, values=[2, 3, 4], axis=0))

    0   1   2
0   2   3   4
1   5   6   7
2   7   8   9

สำหรับnp.insert(df.values, 0, values=[2, 3, 4], axis=0)0 บอกฟังก์ชันสถานที่ / ดัชนีที่คุณต้องการวางค่าใหม่


6

สิ่งนี้อาจดูเรียบง่ายเกินไป แต่เหลือเชื่อที่ฟังก์ชันการแทรกแถวใหม่แบบธรรมดาไม่ได้อยู่ในตัวฉันได้อ่านมากเกี่ยวกับการผนวก df ใหม่เข้ากับต้นฉบับ แต่ฉันสงสัยว่าจะเร็วกว่านี้หรือไม่

df.loc[0] = [row1data, blah...]
i = len(df) + 1
df.loc[i] = [row2data, blah...]

คุณหมายถึง "ต่อท้าย df ใหม่" หรือแค่ "ต่อท้ายแถวใหม่" ตามที่โค้ดของคุณแสดง
smci

ขอโทษประโยคของฉันไม่ชัดเจน ฉันเคยอ่านวิธีแก้ปัญหาของคนอื่นที่ต่อ / ต่อท้าย dataframe ใหม่ทั้งหมดด้วยแถวเดียว แต่ในโซลูชันของฉันมันเป็นเพียงแถวเดียวใน dataframe ที่มีอยู่ไม่จำเป็นต้องสร้าง dataframe เพิ่มเติม
Aaron Melgar

6

ด้านล่างนี้เป็นวิธีที่ดีที่สุดในการแทรกแถวลงในดาต้าเฟรมของแพนด้าโดยไม่ต้องเรียงลำดับและรีเซ็ตดัชนี:

import pandas as pd

df = pd.DataFrame(columns=['a','b','c'])

def insert(df, row):
    insert_loc = df.index.max()

    if pd.isna(insert_loc):
        df.loc[0] = row
    else:
        df.loc[insert_loc + 1] = row

insert(df,[2,3,4])
insert(df,[8,9,0])
print(df)

ทำไมคุณถึงบอกว่านี่เป็นวิธีที่ดีที่สุด
Yuca

ถ้าอย่างนั้นมันจะเป็นการดีที่จะแสดงหลักฐานเพื่อสนับสนุนการอ้างสิทธิ์นั้นคุณถึงเวลาหรือยัง
Yuca

1
คุณสามารถใช้ pd.isna เพื่อหลีกเลี่ยงการนำเข้า numpy
kato2

2

มันค่อนข้างง่ายที่จะเพิ่มแถวลงในหมีแพนด้าDataFrame:

  1. สร้างพจนานุกรมหลามปกติแบบเดียวกับชื่อคอลัมน์เป็นของคุณDataframe;

  2. ใช้pandas.append()method และส่งในชื่อพจนานุกรมของคุณ.append()เมธอดในอินสแตนซ์ DataFrame อยู่ที่ไหน

  3. เพิ่มignore_index=Trueหลังชื่อพจนานุกรมของคุณ


นี่อาจเป็นตัวเลือกที่ดีที่สุด (ประมาณปี 2020)
David Golembiowski

1

concat()ดูเหมือนว่าจะเร็วกว่าการแทรกแถวสุดท้ายและการทำดัชนีใหม่เล็กน้อย ในกรณีที่มีคนสงสัยเกี่ยวกับความเร็วของสองแนวทางยอดนิยม:

In [x]: %%timeit
     ...: df = pd.DataFrame(columns=['a','b'])
     ...: for i in range(10000):
     ...:     df.loc[-1] = [1,2]
     ...:     df.index = df.index + 1
     ...:     df = df.sort_index()

17.1 s ± 705 ms ต่อลูป (ค่าเฉลี่ย± std. dev ของ 7 รัน, 1 ลูปแต่ละอัน)

In [y]: %%timeit
     ...: df = pd.DataFrame(columns=['a', 'b'])
     ...: for i in range(10000):
     ...:     df = pd.concat([pd.DataFrame([[1,2]], columns=df.columns), df])

6.53วินาที± 127 ms ต่อลูป (ค่าเฉลี่ย± std. dev. ของการรัน 7 ครั้งแต่ละลูป 1 ครั้ง)


0

คุณสามารถต่อท้ายแถวที่ส่วนท้ายของ DataFrame จากนั้นปรับดัชนี

ตัวอย่างเช่น:

df = df.append(pd.DataFrame([[2,3,4]],columns=df.columns),ignore_index=True)
df.index = (df.index + 1) % len(df)
df = df.sort_index()

หรือใช้concatเป็น:

df = pd.concat([pd.DataFrame([[1,2,3,4,5,6]],columns=df.columns),df],ignore_index=True)

-1

วิธีที่ง่ายที่สุดในการเพิ่มแถวในกรอบข้อมูลแพนด้าคือ:

DataFrame.loc[ location of insertion ]= list( )

ตัวอย่าง:

DF.loc[ 9 ] = [ ´Pepe , 33, ´Japan ]

หมายเหตุ: ความยาวของรายการของคุณควรตรงกับกรอบข้อมูล

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