วิธีการเปลี่ยนลำดับของคอลัมน์ DataFrame


877

ฉันมีดังต่อไปนี้DataFrame( df):

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 5))

ฉันเพิ่มคอลัมน์เพิ่มเติมโดยการมอบหมาย:

df['mean'] = df.mean(1)

ฉันจะย้ายคอลัมน์meanไปไว้ด้านหน้าได้เช่นตั้งเป็นคอลัมน์แรกโดยไม่เรียงลำดับของคอลัมน์อื่น ๆ


1
การทำซ้ำของPython Pandas ที่
Laurence

1
สำหรับการแก้ปัญหาทั่วไป NumPy ตามดูวิธีการย้ายคอลัมน์ใน dataframe นุ่นMultiIndexถือว่าระดับคอลัมน์เพียงคนเดียวคือไม่มี
jpp

คำตอบ:


853

วิธีง่าย ๆ อย่างหนึ่งคือการมอบหมายดาต้าเฟรมอีกครั้งด้วยรายการของคอลัมน์โดยจัดเรียงใหม่ตามต้องการ

นี่คือสิ่งที่คุณมีตอนนี้:

In [6]: df
Out[6]:
          0         1         2         3         4      mean
0  0.445598  0.173835  0.343415  0.682252  0.582616  0.445543
1  0.881592  0.696942  0.702232  0.696724  0.373551  0.670208
2  0.662527  0.955193  0.131016  0.609548  0.804694  0.632596
3  0.260919  0.783467  0.593433  0.033426  0.512019  0.436653
4  0.131842  0.799367  0.182828  0.683330  0.019485  0.363371
5  0.498784  0.873495  0.383811  0.699289  0.480447  0.587165
6  0.388771  0.395757  0.745237  0.628406  0.784473  0.588529
7  0.147986  0.459451  0.310961  0.706435  0.100914  0.345149
8  0.394947  0.863494  0.585030  0.565944  0.356561  0.553195
9  0.689260  0.865243  0.136481  0.386582  0.730399  0.561593

In [7]: cols = df.columns.tolist()

In [8]: cols
Out[8]: [0L, 1L, 2L, 3L, 4L, 'mean']

จัดเรียงใหม่colsในแบบที่คุณต้องการ นี่คือวิธีที่ฉันย้ายองค์ประกอบสุดท้ายไปยังตำแหน่งแรก:

In [12]: cols = cols[-1:] + cols[:-1]

In [13]: cols
Out[13]: ['mean', 0L, 1L, 2L, 3L, 4L]

จากนั้นเรียงลำดับชื่อไฟล์ใหม่ดังนี้:

In [16]: df = df[cols]  #    OR    df = df.ix[:, cols]

In [17]: df
Out[17]:
       mean         0         1         2         3         4
0  0.445543  0.445598  0.173835  0.343415  0.682252  0.582616
1  0.670208  0.881592  0.696942  0.702232  0.696724  0.373551
2  0.632596  0.662527  0.955193  0.131016  0.609548  0.804694
3  0.436653  0.260919  0.783467  0.593433  0.033426  0.512019
4  0.363371  0.131842  0.799367  0.182828  0.683330  0.019485
5  0.587165  0.498784  0.873495  0.383811  0.699289  0.480447
6  0.588529  0.388771  0.395757  0.745237  0.628406  0.784473
7  0.345149  0.147986  0.459451  0.310961  0.706435  0.100914
8  0.553195  0.394947  0.863494  0.585030  0.565944  0.356561
9  0.561593  0.689260  0.865243  0.136481  0.386582  0.730399

17
ในกรณีที่คุณได้รับ "ไม่สามารถเชื่อมโยงวัตถุ" str "และ" list "" ให้แน่ใจว่าคุณ [] ค่า str ใน cols: cols = [cols [7]] + cols [: 7] + cols [8:]
moeabdol

3
@FooBar นั่นไม่ใช่การรวมกลุ่มมันเป็นการต่อกันของรายการที่เรียงลำดับสองรายการ
Aman

3
@Aman ฉันแค่ชี้ให้เห็นว่ารหัสของคุณเลิกใช้แล้ว การจัดการโพสต์ของคุณขึ้นอยู่กับดุลยพินิจของคุณ
FooBar

2
@FooBar ประเภทของการcolsเป็นlist; มันยังช่วยให้ซ้ำกัน (ซึ่งจะถูกทิ้งเมื่อใช้กับ dataframe) คุณกำลังคิดถึงIndexวัตถุ
alexis

8
นี่หมายถึงการคัดลอกข้อมูลทั้งหมดซึ่งไม่มีประสิทธิภาพสูง ฉันขอหมีแพนด้ามีวิธีการทำเช่นนั้นโดยไม่ต้องสร้างสำเนา
Konstantin

442

คุณสามารถทำสิ่งนี้:

df = df[['mean', '0', '1', '2', '3']]

คุณสามารถรับรายการคอลัมน์ด้วย:

cols = list(df.columns.values)

ผลผลิตจะผลิต:

['0', '1', '2', '3', 'mean']

... ซึ่งง่ายต่อการจัดเรียงใหม่ด้วยตนเองก่อนที่จะวางลงในฟังก์ชันแรก


8
นอกจากนี้คุณยังสามารถรับรายการคอลัมน์พร้อมลิสต์ (df.columns)
Jim

8
หรือdf.columns.tolist()
Jim

สำหรับมือใหม่อย่างฉันจัดรายการใหม่ที่คุณได้รับจาก cols จากนั้น df = df [cols] คือรายการที่จัดเรียงใหม่จะถูกดร็อปลงในนิพจน์แรกโดยไม่มีวงเล็บชุดเดียว
ซิด

ชื่อคอลัมน์จะเป็นจำนวนเต็มใน 3.x df = df[['mean1', 0, 1, 2, 3]]
prosti

1
ฉันไม่คิดว่านี่เป็นคำตอบที่ดีเพราะมันไม่ได้ให้รหัสวิธีเปลี่ยนลำดับคอลัมน์ของดาต้าเฟรมใด ๆ บอกว่าผมนำเข้าไฟล์ CSV เป็นหมีแพนด้า PD pd.read_csv()เป็น คำตอบของคุณจะถูกใช้เพื่อเปลี่ยนลำดับคอลัมน์ได้อย่างไร
Robvh

312

เพียงกำหนดชื่อคอลัมน์ตามลำดับที่คุณต้องการ:

In [39]: df
Out[39]: 
          0         1         2         3         4  mean
0  0.172742  0.915661  0.043387  0.712833  0.190717     1
1  0.128186  0.424771  0.590779  0.771080  0.617472     1
2  0.125709  0.085894  0.989798  0.829491  0.155563     1
3  0.742578  0.104061  0.299708  0.616751  0.951802     1
4  0.721118  0.528156  0.421360  0.105886  0.322311     1
5  0.900878  0.082047  0.224656  0.195162  0.736652     1
6  0.897832  0.558108  0.318016  0.586563  0.507564     1
7  0.027178  0.375183  0.930248  0.921786  0.337060     1
8  0.763028  0.182905  0.931756  0.110675  0.423398     1
9  0.848996  0.310562  0.140873  0.304561  0.417808     1

In [40]: df = df[['mean', 4,3,2,1]]

ตอนนี้คอลัมน์ 'mean' จะออกมาด้านหน้า:

In [41]: df
Out[41]: 
   mean         4         3         2         1
0     1  0.190717  0.712833  0.043387  0.915661
1     1  0.617472  0.771080  0.590779  0.424771
2     1  0.155563  0.829491  0.989798  0.085894
3     1  0.951802  0.616751  0.299708  0.104061
4     1  0.322311  0.105886  0.421360  0.528156
5     1  0.736652  0.195162  0.224656  0.082047
6     1  0.507564  0.586563  0.318016  0.558108
7     1  0.337060  0.921786  0.930248  0.375183
8     1  0.423398  0.110675  0.931756  0.182905
9     1  0.417808  0.304561  0.140873  0.310562

7
มันทำสำเนาหรือไม่?
user3226167

21
@NicholasMorley - นี่ไม่ใช่คำตอบที่ดีที่สุดถ้าคุณมีพูด 1,000 คอลัมน์ใน df ของคุณ
AGS

1
ดูเหมือนว่าคุณจะไม่ได้รับ<df>.columnsสิทธิ์เหมือนที่คุณอ้างสิทธิ์ในตอนแรก
แฟน ๆ หมายเลขหนึ่งของ Bjorks

8
นี่คือคำตอบที่ดีที่สุดสำหรับคอลัมน์จำนวนน้อย
Dongkyu Choi

2
นี่เป็นเพียงสำเนาของคำตอบก่อนหน้าของ @freddygv นั่นควรเป็นคำตอบที่ยอมรับไม่ใช่อย่างนี้
James Hirschorn

134

เกี่ยวกับ:

df.insert(0, 'mean', df.mean(1))

http://pandas.pydata.org/pandas-docs/stable/dsintro.html#column-selection-addition-deletion


35
นี่อาจเป็นคุณสมบัติในอนาคตที่จะเพิ่มไปpandas? สิ่งที่ชอบdf.move(0,df.mean)?
jason

โอ้ก็ยังทำงานเช่นนี้df_metadata.insert(0,'Db_name',"raw_data")(รหัสไม่เกี่ยวข้องกับหัวข้อนี้)
Aetos

3
สวย. และมันก็เกิดขึ้นในสถานที่เช่นกัน
cucu8

2
นี่เป็นโซลูชันที่ปรับขนาดได้เนื่องจากโซลูชันอื่นกำลังพิมพ์ชื่อคอลัมน์ด้วยตนเอง
CKM

สิ่งนี้ใช้ได้กับคำถามของ OP เมื่อสร้างคอลัมน์ใหม่ แต่ไม่ได้สำหรับการย้ายคอลัมน์ พยายามย้ายผลลัพธ์ใน*** ValueError: cannot insert mean, already exists
spinup

122

ในกรณีของคุณ

df = df.reindex(columns=['mean',0,1,2,3,4])

จะทำสิ่งที่คุณต้องการ

ในกรณีของฉัน (แบบฟอร์มทั่วไป):

df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=(['opened'] + list([a for a in df.columns if a != 'opened']) ))

2
ฉันพยายามตั้งค่าcopy=Falseแต่ดูเหมือนว่าreindex_axisจะยังคงสร้างสำเนาอยู่
Konstantin

1
@Konstantin คุณสามารถสร้างคำถามเกี่ยวกับปัญหานี้อีกหรือไม่ มันจะเป็นการดีกว่าถ้ามีบริบทมากขึ้น
อัลวาโรโจอา

57

คุณต้องสร้างรายการใหม่ของคอลัมน์ตามลำดับที่ต้องการจากนั้นใช้df = df[cols]เพื่อจัดเรียงคอลัมน์ตามลำดับใหม่นี้

cols = ['mean']  + [col for col in df if col != 'mean']
df = df[cols]

นอกจากนี้คุณยังสามารถใช้วิธีการทั่วไปเพิ่มเติม ในตัวอย่างนี้แทรกคอลัมน์สุดท้าย (ระบุโดย -1) เป็นคอลัมน์แรก

cols = [df.columns[-1]] + [col for col in df if col != df.columns[-1]]
df = df[cols]

คุณยังสามารถใช้วิธีนี้ในการจัดลำดับคอลัมน์ใหม่ตามลำดับที่ต้องการหากมีอยู่ใน DataFrame

inserted_cols = ['a', 'b', 'c']
cols = ([col for col in inserted_cols if col in df] 
        + [col for col in df if col not in inserted_cols])
df = df[cols]

45
import numpy as np
import pandas as pd
df = pd.DataFrame()
column_names = ['x','y','z','mean']
for col in column_names: 
    df[col] = np.random.randint(0,100, size=10000)

คุณสามารถลองวิธีแก้ไขปัญหาต่อไปนี้:

โซลูชันที่ 1:

df = df[ ['mean'] + [ col for col in df.columns if col != 'mean' ] ]

โซลูชันที่ 2:


df = df[['mean', 'x', 'y', 'z']]

โซลูชันที่ 3:

col = df.pop("mean")
df = df.insert(0, col.name, col)

โซลูชันที่ 4:

df.set_index(df.columns[-1], inplace=True)
df.reset_index(inplace=True)

โซลูชันที่ 5:

cols = list(df)
cols = [cols[-1]] + cols[:-1]
df = df[cols]

โซลูชันที่ 6:

order = [1,2,3,0] # setting column's order
df = df[[df.columns[i] for i in order]]

เปรียบเทียบเวลา:

โซลูชันที่ 1:

เวลาซีพียู: ผู้ใช้ 1.05 ms, sys: 35 ,s, ทั้งหมด: 1.08 ms เวลาผนัง: 995 µs

โซลูชันที่ 2 :

เวลาซีพียู: ผู้ใช้ 933 ,s, sys: 0 ns, ทั้งหมด: 933 µs เวลาผนัง: 800 µs

โซลูชันที่ 3 :

เวลาซีพียู: ผู้ใช้ 0 ns, sys: 1.35 ms, ทั้งหมด: 1.35 ms เวลาผนัง: 1.08 ms

โซลูชันที่ 4 :

เวลาซีพียู: ผู้ใช้ 1.23 ms, sys: 45 ,s, ทั้งหมด: 1.27 ms เวลาผนัง: 986 µs

โซลูชันที่ 5 :

เวลาซีพียู: ผู้ใช้ 1.09 ms, sys: 19 µs, ทั้งหมด: 1.11 ms เวลาผนัง: 949 µs

โซลูชันที่ 6 :

เวลาซีพียู: ผู้ใช้ 955 ,s, sys: 34 totals, ทั้งหมด: 989 µs เวลาผนัง: 859 µs


1
ช่างเป็นคำตอบที่สวยงามขอบคุณ
qasimalbaqali

1
โซลูชันที่ 1 คือสิ่งที่ฉันต้องการเนื่องจากฉันมีคอลัมน์มากเกินไป (53) ขอบคุณ
ratnesh

@Pygirl ค่าที่แสดงเวลา comsumed จริงหรือไม่ (ผู้ใช้ sys เวลาทั้งหมดหรือเวลาผ่านกำแพง)
sergzemsk

1
นี่คือคำตอบที่ดีที่สุดสำหรับฉัน โซลูชั่นมากมาย (รวมถึงโซลูชันที่ฉันต้องการ) และวิธีการง่าย ๆ ขอบคุณ!
Gustavo Rottgering

1
โซลูชันที่ 6 (ไม่มีความเข้าใจในรายการ):df = df.iloc[:, [1, 2, 3, 0]]
Dmitriy Work

43

ตั้งแต่สิงหาคม 2561:

หากชื่อคอลัมน์ของคุณยาวเกินไปที่จะพิมพ์คุณสามารถระบุคำสั่งซื้อใหม่ผ่านรายการจำนวนเต็มพร้อมตำแหน่ง:

ข้อมูล:

          0         1         2         3         4      mean
0  0.397312  0.361846  0.719802  0.575223  0.449205  0.500678
1  0.287256  0.522337  0.992154  0.584221  0.042739  0.485741
2  0.884812  0.464172  0.149296  0.167698  0.793634  0.491923
3  0.656891  0.500179  0.046006  0.862769  0.651065  0.543382
4  0.673702  0.223489  0.438760  0.468954  0.308509  0.422683
5  0.764020  0.093050  0.100932  0.572475  0.416471  0.389390
6  0.259181  0.248186  0.626101  0.556980  0.559413  0.449972
7  0.400591  0.075461  0.096072  0.308755  0.157078  0.207592
8  0.639745  0.368987  0.340573  0.997547  0.011892  0.471749
9  0.050582  0.714160  0.168839  0.899230  0.359690  0.438500

ตัวอย่างทั่วไป:

new_order = [3,2,1,4,5,0]
print(df[df.columns[new_order]])  

          3         2         1         4      mean         0
0  0.575223  0.719802  0.361846  0.449205  0.500678  0.397312
1  0.584221  0.992154  0.522337  0.042739  0.485741  0.287256
2  0.167698  0.149296  0.464172  0.793634  0.491923  0.884812
3  0.862769  0.046006  0.500179  0.651065  0.543382  0.656891
4  0.468954  0.438760  0.223489  0.308509  0.422683  0.673702
5  0.572475  0.100932  0.093050  0.416471  0.389390  0.764020
6  0.556980  0.626101  0.248186  0.559413  0.449972  0.259181
7  0.308755  0.096072  0.075461  0.157078  0.207592  0.400591
8  0.997547  0.340573  0.368987  0.011892  0.471749  0.639745
9  0.899230  0.168839  0.714160  0.359690  0.438500  0.050582

และสำหรับกรณีเฉพาะของคำถามของ OP:

new_order = [-1,0,1,2,3,4]
df = df[df.columns[new_order]]
print(df)

       mean         0         1         2         3         4
0  0.500678  0.397312  0.361846  0.719802  0.575223  0.449205
1  0.485741  0.287256  0.522337  0.992154  0.584221  0.042739
2  0.491923  0.884812  0.464172  0.149296  0.167698  0.793634
3  0.543382  0.656891  0.500179  0.046006  0.862769  0.651065
4  0.422683  0.673702  0.223489  0.438760  0.468954  0.308509
5  0.389390  0.764020  0.093050  0.100932  0.572475  0.416471
6  0.449972  0.259181  0.248186  0.626101  0.556980  0.559413
7  0.207592  0.400591  0.075461  0.096072  0.308755  0.157078
8  0.471749  0.639745  0.368987  0.340573  0.997547  0.011892
9  0.438500  0.050582  0.714160  0.168839  0.899230  0.359690

ปัญหาหลักของวิธีนี้คือการเรียกรหัสเดียวกันหลาย ๆ ครั้งจะสร้างผลลัพธ์ที่แตกต่างกันในแต่ละครั้งดังนั้นจึงต้องระวัง :)


17

ฟังก์ชั่นนี้จะช่วยให้คุณไม่ต้องเขียนรายการตัวแปรทุกตัวในชุดข้อมูลของคุณเพียงแค่สั่งซื้อบางส่วนของมัน

def order(frame,var):
    if type(var) is str:
        var = [var] #let the command take a string or list
    varlist =[w for w in frame.columns if w not in var]
    frame = frame[var+varlist]
    return frame 

มันต้องใช้สองข้อโต้แย้งแรกคือชุดข้อมูลที่สองคือคอลัมน์ในชุดข้อมูลที่คุณต้องการที่จะนำไปข้างหน้า

ในกรณีของฉันฉันมีชุดข้อมูลชื่อ Frame พร้อมตัวแปร A1, A2, B1, B2, Total และ Date ถ้าฉันต้องการนำ Total ไปไว้ข้างหน้าสิ่งที่ฉันต้องทำคือ:

frame = order(frame,['Total'])

ถ้าฉันต้องการนำผลรวมและวันที่มาไว้ข้างหน้าฉันจะทำ:

frame = order(frame,['Total','Date'])

แก้ไข:

อีกวิธีที่มีประโยชน์ในการใช้นี่คือถ้าคุณมีตารางที่ไม่คุ้นเคยและคุณกำลังค้นหาตัวแปรที่มีคำเฉพาะในพวกเขาเช่น VAR1, VAR2, ... คุณอาจดำเนินการดังนี้:

frame = order(frame,[v for v in frame.columns if "VAR" in v])

17

ฉันพบคำถามที่คล้ายกันด้วยตัวเองและต้องการเพิ่มสิ่งที่ฉันตัดสิน ฉันชอบการreindex_axis() methodเปลี่ยนลำดับคอลัมน์ สิ่งนี้ได้ผล:

df = df.reindex_axis(['mean'] + list(df.columns[:-1]), axis=1)

วิธีอื่นตามความคิดเห็นจาก @Jorge:

df = df.reindex(columns=['mean'] + list(df.columns[:-1]))

แม้ว่าreindex_axisดูเหมือนว่าจะเร็วกว่าเล็กน้อยในการวัดขนาดเล็กกว่าreindexฉันคิดว่าฉันชอบอันหลังสำหรับความตรง


6
นี่เป็นวิธีที่ดี แต่ reindex_axis จะถูกปฏิเสธ ฉันใช้การสร้างดัชนีใหม่และมันก็ใช้ได้ดี
Jorge

15

เพียงทำ

df = df[['mean'] + df.columns[:-1].tolist()]

TypeError: ไม่สามารถแปลงวัตถุ 'int' เป็น str โดยปริยาย
parvij

อาจเป็น API ที่มีการเปลี่ยนแปลงคุณยังสามารถทำสิ่งนี้ได้ ... order = df.columns.tolist() df['mean'] = df.mean(1) df.columns = ['mean'] + order
Napitupulu Jon

1
ความหลากหลายของสิ่งนี้ใช้ได้ดีสำหรับฉัน กับรายการที่มีอยู่headersที่ใช้ในการสร้างกิงดิคที่ถูกนำมาใช้เพื่อสร้าง DataFrame df.reindex(columns=headers)ที่ฉันเรียกว่า ปัญหาเดียวที่ฉันพบคือฉันได้เรียกไปแล้วdf.set_index('some header name', inplace=True)ดังนั้นเมื่อการทำดัชนีใหม่เสร็จแล้วมันจะเพิ่มคอลัมน์อื่นที่ชื่อว่าsome header nameเนื่องจากคอลัมน์เดิมตอนนี้เป็นดัชนี สำหรับไวยากรณ์ที่ระบุข้างต้น['mean'] + df.columnsในล่ามหลามให้ฉันIndex(u'meanAddress', u'meanCity', u'meanFirst Name'...
hlongmore

1
@hlongmore: ฉันไม่ทราบรหัสของคุณก่อน แต่การแก้ไขควรจะทำงาน (ใช้ 0.19.2)
Napitupulu จอน

การแก้ไขใช้งานได้จริง (ฉันใช้ 0.20.2) ในกรณีของฉันฉันมีคอลัมน์ที่ฉันต้องการอยู่แล้วดังนั้นฉันจึงคิดว่า df.reindex () เป็นสิ่งที่ฉันควรใช้จริง ๆ
hlongmore

11

คุณสามารถทำสิ่งต่อไปนี้ (ยืมส่วนจากคำตอบของ Aman):

cols = df.columns.tolist()
cols.insert(0, cols.pop(-1))

cols
>>>['mean', 0L, 1L, 2L, 3L, 4L]

df = df[cols]

10

เพียงพิมพ์ชื่อคอลัมน์ที่คุณต้องการเปลี่ยนและตั้งค่าดัชนีสำหรับตำแหน่งใหม่

def change_column_order(df, col_name, index):
    cols = df.columns.tolist()
    cols.remove(col_name)
    cols.insert(index, col_name)
    return df[cols]

สำหรับกรณีของคุณนี่จะเป็นเช่น:

df = change_column_order(df, 'mean', 0)

นี่เป็น underrated
zelusp

8

ย้ายคอลัมน์ไปยังตำแหน่งใด ๆ :

import pandas as pd
df = pd.DataFrame({"A": [1,2,3], 
                   "B": [2,4,8], 
                   "C": [5,5,5]})

cols = df.columns.tolist()
column_to_move = "C"
new_position = 1

cols.insert(new_position, cols.pop(cols.index(column_to_move)))
df = df[cols]

7

ฉันคิดว่านี่เป็นวิธีแก้ปัญหา neater เล็กน้อย:

df.insert(0,'mean', df.pop("mean"))

โซลูชันนี้ค่อนข้างคล้ายกับโซลูชันของ @JoeHeffer แต่นี่เป็นหนึ่งซับ

ที่นี่เราลบคอลัมน์"mean"ออกจาก dataframe และแนบกับดัชนีที่0มีชื่อคอลัมน์เดียวกัน


5

ต่อไปนี้เป็นวิธีย้ายหนึ่งคอลัมน์ที่มีอยู่ซึ่งจะแก้ไข data frame ที่มีอยู่

my_column = df.pop('column name')
df.insert(3, my_column.name, my_column)

5

คำถามนี้ได้รับการตอบก่อนหน้านี้แต่ reindex_axis เลิกใช้แล้วดังนั้นฉันขอแนะนำให้ใช้:

df.reindex(sorted(df.columns), axis=1)

19
ไม่แตกต่างกัน ผู้ใช้ต้องการเรียงลำดับคอลัมน์ทั้งหมดตามชื่อ ที่นี่พวกเขาต้องการย้ายคอลัมน์หนึ่งไปยังคอลัมน์แรกในขณะที่ไม่ได้เรียงลำดับของคอลัมน์อื่น ๆ
smci

1
ถ้าคุณไม่ต้องการให้พวกเขาเรียงลำดับ?
Chankey Pathak

สิ่งนี้ส่งคืนสำเนาไม่ทำงานแทน
spinup


3

@clocker: โซลูชันของคุณมีประโยชน์มากสำหรับฉันเนื่องจากฉันต้องการนำคอลัมน์สองคอลัมน์มาด้านหน้าจาก dataframe ที่ฉันไม่ทราบชื่อของคอลัมน์ทั้งหมดอย่างชัดเจนเพราะพวกเขาสร้างขึ้นจากคำสั่ง pivot มาก่อน ดังนั้นถ้าคุณอยู่ในสถานการณ์เดียวกัน: เมื่อต้องการนำคอลัมน์ข้างหน้าที่คุณรู้จักชื่อแล้วให้พวกเขาตามด้วย "คอลัมน์อื่น ๆ ทั้งหมด" ฉันมาด้วยวิธีแก้ปัญหาทั่วไปดังต่อไปนี้

df = df.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)

3

set():

ใช้วิธีการง่ายๆโดยset()เฉพาะอย่างยิ่งเมื่อคุณมีรายการคอลัมน์ที่ยาวและไม่ต้องการจัดการด้วยตนเอง:

cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]

2
ข้อควรระวังหนึ่งประการ: ลำดับของคอลัมน์จะหายไปหากคุณใส่ไว้ในชุด
pvarma

! ที่น่าสนใจ @ user1930402 ฉันได้ลองวิธีการข้างต้นหลายครั้งและไม่เคยมีปัญหาใด ๆ ฉันจะตรวจสอบอีกครั้ง
Shoresh

2

ฉันชอบคำตอบของ Shoreshจะใช้ฟังก์ชั่นการตั้งค่าเพื่อลบคอลัมน์เมื่อคุณไม่ทราบตำแหน่ง แต่สิ่งนี้ไม่ได้ผลสำหรับวัตถุประสงค์ของฉันเนื่องจากฉันต้องการรักษาลำดับคอลัมน์เดิม (ซึ่งมีป้ายกำกับคอลัมน์แบบกำหนดเอง)

ฉันได้รับการทำงานแม้ว่าโดยใช้IndexedSetจากแพ็คเกจโบลตัน

ฉันยังต้องการเพิ่มป้ายกำกับคอลัมน์อีกหลายรายการดังนั้นสำหรับกรณีทั่วไปที่มากกว่าฉันใช้รหัสต่อไปนี้:

from boltons.setutils import IndexedSet
cols = list(IndexedSet(df.columns.tolist()) - set(['mean', 'std']))
cols[0:0] =['mean', 'std']
df = df[cols]

หวังว่านี่จะเป็นประโยชน์กับทุกคนที่ค้นหาหัวข้อนี้สำหรับการแก้ปัญหาทั่วไป


ฉันรู้สึกประหลาดใจเล็กน้อย! ฉันใช้setเพื่อจุดประสงค์นี้ค่อนข้างบ่อยและไม่เคยจัดการกับการสั่งซื้อ
Shoresh

2

คุณสามารถใช้reindexซึ่งสามารถใช้สำหรับแกนทั้งสอง:

df
#           0         1         2         3         4      mean
# 0  0.943825  0.202490  0.071908  0.452985  0.678397  0.469921
# 1  0.745569  0.103029  0.268984  0.663710  0.037813  0.363821
# 2  0.693016  0.621525  0.031589  0.956703  0.118434  0.484254
# 3  0.284922  0.527293  0.791596  0.243768  0.629102  0.495336
# 4  0.354870  0.113014  0.326395  0.656415  0.172445  0.324628
# 5  0.815584  0.532382  0.195437  0.829670  0.019001  0.478415
# 6  0.944587  0.068690  0.811771  0.006846  0.698785  0.506136
# 7  0.595077  0.437571  0.023520  0.772187  0.862554  0.538182
# 8  0.700771  0.413958  0.097996  0.355228  0.656919  0.444974
# 9  0.263138  0.906283  0.121386  0.624336  0.859904  0.555009

df.reindex(['mean', *range(5)], axis=1)

#        mean         0         1         2         3         4
# 0  0.469921  0.943825  0.202490  0.071908  0.452985  0.678397
# 1  0.363821  0.745569  0.103029  0.268984  0.663710  0.037813
# 2  0.484254  0.693016  0.621525  0.031589  0.956703  0.118434
# 3  0.495336  0.284922  0.527293  0.791596  0.243768  0.629102
# 4  0.324628  0.354870  0.113014  0.326395  0.656415  0.172445
# 5  0.478415  0.815584  0.532382  0.195437  0.829670  0.019001
# 6  0.506136  0.944587  0.068690  0.811771  0.006846  0.698785
# 7  0.538182  0.595077  0.437571  0.023520  0.772187  0.862554
# 8  0.444974  0.700771  0.413958  0.097996  0.355228  0.656919
# 9  0.555009  0.263138  0.906283  0.121386  0.624336  0.859904

2

นี่คือฟังก์ชั่นการทำเช่นนี้สำหรับคอลัมน์จำนวนเท่าใดก็ได้

def mean_first(df):
    ncols = df.shape[1]        # Get the number of columns
    index = list(range(ncols)) # Create an index to reorder the columns
    index.insert(0,ncols)      # This puts the last column at the front
    return(df.assign(mean=df.mean(1)).iloc[:,index]) # new df with last column (mean) first

2

วิธีการแฮ็กที่สุดในหนังสือ

df.insert(0,"test",df["mean"])
df=df.drop(columns=["mean"]).rename(columns={"test":"mean"})

2

ฉันคิดว่าฟังก์ชั่นนี้ตรงไปตรงมามากขึ้น คุณเพียงแค่ต้องระบุชุดย่อยของคอลัมน์ที่จุดเริ่มต้นหรือจุดสิ้นสุดหรือทั้งสอง:

def reorder_df_columns(df, start=None, end=None):
    """
        This function reorder columns of a DataFrame.
        It takes columns given in the list `start` and move them to the left.
        Its also takes columns in `end` and move them to the right.
    """
    if start is None:
        start = []
    if end is None:
        end = []
    assert isinstance(start, list) and isinstance(end, list)
    cols = list(df.columns)
    for c in start:
        if c not in cols:
            start.remove(c)
    for c in end:
        if c not in cols or c in start:
            end.remove(c)
    for c in start + end:
        cols.remove(c)
    cols = start + cols + end
    return df[cols]

1

ฉันเชื่อว่าคำตอบของ @Amanดีที่สุดหากคุณทราบตำแหน่งของคอลัมน์อื่น

หากคุณไม่ทราบว่าสถานที่ตั้งของแต่มีเพียงชื่อของมันคุณไม่สามารถรีสอร์ทโดยตรงกับmean cols = cols[-1:] + cols[:-1]ต่อไปนี้เป็นสิ่งที่ดีที่สุดถัดไปที่ฉันจะได้รับ:

meanDf = pd.DataFrame(df.pop('mean'))
# now df doesn't contain "mean" anymore. Order of join will move it to left or right:
meanDf.join(df) # has mean as first column
df.join(meanDf) # has mean as last column

1

เพียงแค่พลิกช่วยบ่อย

df[df.columns[::-1]]

หรือเพียงแค่สับเปลี่ยนเพื่อดู

import random
cols = list(df.columns)
random.shuffle(cols)
df[cols]

0

คำตอบส่วนใหญ่ไม่ได้พูดคุยมากพอและวิธีการ pandas reindex_axis นั้นค่อนข้างน่าเบื่อดังนั้นฉันจึงเสนอฟังก์ชั่นที่ง่ายในการย้ายจำนวนคอลัมน์ไปยังตำแหน่งใด ๆ โดยใช้พจนานุกรมโดยที่คีย์ = ชื่อคอลัมน์และค่า = ตำแหน่งที่จะย้ายไป หาก dataframe ของคุณมีขนาดใหญ่ผ่าน True เป็น 'big_data' แล้วฟังก์ชันจะส่งกลับรายการคอลัมน์ที่สั่งซื้อ และคุณสามารถใช้รายการนี้เพื่อแบ่งข้อมูลของคุณ

def order_column(df, columns, big_data = False):

    """Re-Orders dataFrame column(s)
       Parameters : 
       df      -- dataframe
       columns -- a dictionary:
                  key   = current column position/index or column name
                  value = position to move it to  
       big_data -- boolean 
                  True = returns only the ordered columns as a list
                          the user user can then slice the data using this
                          ordered column
                  False = default - return a copy of the dataframe
    """
    ordered_col = df.columns.tolist()

    for key, value in columns.items():

        ordered_col.remove(key)
        ordered_col.insert(value, key)

    if big_data:

        return ordered_col

    return df[ordered_col]

# e.g.
df = pd.DataFrame({'chicken wings': np.random.rand(10, 1).flatten(), 'taco': np.random.rand(10,1).flatten(),
                          'coffee': np.random.rand(10, 1).flatten()})
df['mean'] = df.mean(1)

df = order_column(df, {'mean': 0, 'coffee':1 })

>>>

เอาท์พุต

col = order_column(df, {'mean': 0, 'coffee':1 }, True)

col
>>>
['mean', 'coffee', 'chicken wings', 'taco']

# you could grab it by doing this

df = df[col]

0

ฉันมีกรณีการใช้งานที่เฉพาะเจาะจงมากสำหรับการสั่งซื้อชื่อคอลัมน์ในแพนด้าอีกครั้ง บางครั้งฉันกำลังสร้างคอลัมน์ใหม่ใน dataframe ที่เป็นไปตามคอลัมน์ที่มีอยู่ โดยค่าเริ่มต้นหมีแพนด้าจะแทรกคอลัมน์ใหม่ของฉันในตอนท้าย แต่ฉันต้องการให้แทรกคอลัมน์ใหม่ถัดจากคอลัมน์ที่มีอยู่

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

def rearrange_list(input_list, input_item_to_move, input_item_insert_here):
    '''
    Helper function to re-arrange the order of items in a list.
    Useful for moving column in pandas dataframe.

    Inputs:
        input_list - list
        input_item_to_move - item in list to move
        input_item_insert_here - item in list, insert before 

    returns:
        output_list
    '''
    # make copy for output, make sure it's a list
    output_list = list(input_list)

    # index of item to move
    idx_move = output_list.index(input_item_to_move)

    # pop off the item to move
    itm_move = output_list.pop(idx_move)

    # index of item to insert here
    idx_insert = output_list.index(input_item_insert_here)

    # insert item to move into here
    output_list.insert(idx_insert, itm_move)

    return output_list


import pandas as pd

# step 1: create sample dataframe
df = pd.DataFrame({
    'motorcycle': ['motorcycle1', 'motorcycle2', 'motorcycle3'],
    'initial_odometer': [101, 500, 322],
    'final_odometer': [201, 515, 463],
    'other_col_1': ['blah', 'blah', 'blah'],
    'other_col_2': ['blah', 'blah', 'blah']
})
print('Step 1: create sample dataframe')
display(df)
print()

# step 2: add new column that is difference between final and initial
df['change_odometer'] = df['final_odometer']-df['initial_odometer']
print('Step 2: add new column')
display(df)
print()

# step 3: rearrange columns
ls_cols = df.columns
ls_cols = rearrange_list(ls_cols, 'change_odometer', 'final_odometer')
df=df[ls_cols]
print('Step 3: rearrange columns')
display(df)

0

วิธีแก้ปัญหาที่ตรงไปตรงมาสำหรับฉันคือใช้. index บน df.columns:

df=df[df.columns.reindex(['mean',0,1,2,3,4])[0]]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.