Pandas - วิธีการทำให้ดัชนีลำดับขั้นในคอลัมน์แบนเรียบ


325

ฉันมีกรอบข้อมูลที่มีดัชนีลำดับชั้นในแกน 1 (คอลัมน์) (จากการgroupby.aggดำเนินการ):

     USAF   WBAN  year  month  day  s_PC  s_CL  s_CD  s_CNT  tempf       
                                     sum   sum   sum    sum   amax   amin
0  702730  26451  1993      1    1     1     0    12     13  30.92  24.98
1  702730  26451  1993      1    2     0     0    13     13  32.00  24.98
2  702730  26451  1993      1    3     1    10     2     13  23.00   6.98
3  702730  26451  1993      1    4     1     0    12     13  10.04   3.92
4  702730  26451  1993      1    5     3     0    10     13  19.94  10.94

ฉันต้องการทำให้แบนเพื่อให้ดูเหมือนว่า (ชื่อไม่สำคัญ - ฉันสามารถเปลี่ยนชื่อ):

     USAF   WBAN  year  month  day  s_PC  s_CL  s_CD  s_CNT  tempf_amax  tmpf_amin   
0  702730  26451  1993      1    1     1     0    12     13  30.92          24.98
1  702730  26451  1993      1    2     0     0    13     13  32.00          24.98
2  702730  26451  1993      1    3     1    10     2     13  23.00          6.98
3  702730  26451  1993      1    4     1     0    12     13  10.04          3.92
4  702730  26451  1993      1    5     3     0    10     13  19.94          10.94

ฉันจะทำสิ่งนี้ได้อย่างไร (ฉันได้ลองมาหลายครั้งแล้วโดยไม่มีประโยชน์)

ต่อคำแนะนำนี่คือหัวในรูปแบบ dict

{('USAF', ''): {0: '702730',
  1: '702730',
  2: '702730',
  3: '702730',
  4: '702730'},
 ('WBAN', ''): {0: '26451', 1: '26451', 2: '26451', 3: '26451', 4: '26451'},
 ('day', ''): {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
 ('month', ''): {0: 1, 1: 1, 2: 1, 3: 1, 4: 1},
 ('s_CD', 'sum'): {0: 12.0, 1: 13.0, 2: 2.0, 3: 12.0, 4: 10.0},
 ('s_CL', 'sum'): {0: 0.0, 1: 0.0, 2: 10.0, 3: 0.0, 4: 0.0},
 ('s_CNT', 'sum'): {0: 13.0, 1: 13.0, 2: 13.0, 3: 13.0, 4: 13.0},
 ('s_PC', 'sum'): {0: 1.0, 1: 0.0, 2: 1.0, 3: 1.0, 4: 3.0},
 ('tempf', 'amax'): {0: 30.920000000000002,
  1: 32.0,
  2: 23.0,
  3: 10.039999999999999,
  4: 19.939999999999998},
 ('tempf', 'amin'): {0: 24.98,
  1: 24.98,
  2: 6.9799999999999969,
  3: 3.9199999999999982,
  4: 10.940000000000001},
 ('year', ''): {0: 1993, 1: 1993, 2: 1993, 3: 1993, 4: 1993}}

5
คุณสามารถเพิ่มเอาท์พุทdf[:5].to_dict()เป็นตัวอย่างให้คนอื่นอ่านในชุดข้อมูลของคุณได้หรือไม่?
Zelazny7

ความคิดที่ดี. ทำข้างบนหรือไม่เพราะมันยาวเกินไปสำหรับความคิดเห็น
Ross R

มีข้อเสนอแนะเกี่ยวกับpandasตัวติดตามปัญหาเพื่อใช้วิธีการเฉพาะสำหรับสิ่งนี้
joelostblom

2
@joelostblom และมีการใช้งานจริงแล้ว (pandas 0.24.0 ขึ้นไป) ผมโพสต์คำตอบdat.columns = dat.columns.to_flat_index()แต่เป็นหลักตอนนี้คุณก็สามารถทำ ฟังก์ชั่นแพนด้าในตัว
onlyphantom

คำตอบ:


471

ฉันคิดว่าวิธีที่ง่ายที่สุดในการทำเช่นนี้คือการกำหนดคอลัมน์ให้อยู่ในระดับสูงสุด:

df.columns = df.columns.get_level_values(0)

หมายเหตุ: หากระดับถึงมีชื่อคุณสามารถเข้าถึงได้โดยใช้ชื่อนี้แทนที่จะเป็น 0

.

หากคุณต้องการที่จะรวม / joinMultiIndex ของคุณเป็นหนึ่งดัชนี(สมมติว่าคุณมีเพียงรายการสตริงในคอลัมน์ของคุณ)คุณสามารถ:

df.columns = [' '.join(col).strip() for col in df.columns.values]

หมายเหตุ: เราต้องstripเว้นช่องว่างสำหรับเมื่อไม่มีดัชนีที่สอง

In [11]: [' '.join(col).strip() for col in df.columns.values]
Out[11]: 
['USAF',
 'WBAN',
 'day',
 'month',
 's_CD sum',
 's_CL sum',
 's_CNT sum',
 's_PC sum',
 'tempf amax',
 'tempf amin',
 'year']

14
df.reset_index (inplace = True)อาจเป็นโซลูชันทางเลือก
โทเบียส

8
หนึ่งความคิดเห็นเล็กน้อย ... หากคุณต้องการใช้ _ สำหรับคอลัมน์รวมหลายระดับ .. คุณสามารถใช้ ... df.columns = ['_'. เข้าร่วม (col) .strip () สำหรับ col ใน df.columns ค่า]
ihightower

30
การปรับเปลี่ยนเล็กน้อยเพื่อรักษาขีดล่างสำหรับคอลัมน์ที่เข้าร่วมเท่านั้น:['_'.join(col).rstrip('_') for col in df.columns.values]
Seiji Armstrong

สิ่งนี้ใช้งานได้ดีถ้าคุณต้องการใช้คอลัมน์ที่สอง: df.columns = [col [1] สำหรับ col ใน df.columns.values]
user3078500

1
หากคุณต้องการที่จะใช้sum s_CDแทนการหนึ่งที่สามารถทำs_CD sum df.columns = ['_'.join(col).rstrip('_') for col in [c[::-1] for c in df.columns.values]]
irene

82
pd.DataFrame(df.to_records()) # multiindex become columns and new index is integers only

3
วิธีนี้ใช้ได้ผล แต่ออกจากชื่อคอลัมน์ซึ่งเข้าถึงได้ยากโดยทางโปรแกรมและไม่สามารถสอบถามได้
dmeu

1
สิ่งนี้จะไม่ทำงานกับนุ่นรุ่นล่าสุด ใช้งานได้กับ 0.18 แต่ไม่ใช่กับ 0.20 (ล่าสุดจนถึงตอนนี้)
TH22

1
@dmeu เพื่อรักษาชื่อคอลัมน์ pd.DataFrame(df.to_records(), columns=df.index.names + list(df.columns))
Teoretic

1
มันคือการรักษาชื่อคอลัมน์เป็นสิ่งอันดับสำหรับฉันและเพื่อให้ดัชนีฉันใช้:pd.DataFrame(df_volume.to_records(), index=df_volume.index).drop('index', axis=1)
34717

54

คำตอบปัจจุบันทั้งหมดในกระทู้นี้ต้องเป็นวันที่เล็กน้อย ในฐานะของpandasรุ่น 0.24.0 การ.to_flat_index()ทำสิ่งที่คุณต้องการ

จากเอกสารของแพนด้า:

MultiIndex.to_flat_index ()

แปลง MultiIndex เป็นดัชนีของ Tuples ที่มีค่าระดับ

ตัวอย่างง่ายๆจากเอกสาร:

import pandas as pd
print(pd.__version__) # '0.23.4'
index = pd.MultiIndex.from_product(
        [['foo', 'bar'], ['baz', 'qux']],
        names=['a', 'b'])

print(index)
# MultiIndex(levels=[['bar', 'foo'], ['baz', 'qux']],
#           codes=[[1, 1, 0, 0], [0, 1, 0, 1]],
#           names=['a', 'b'])

การใช้to_flat_index():

index.to_flat_index()
# Index([('foo', 'baz'), ('foo', 'qux'), ('bar', 'baz'), ('bar', 'qux')], dtype='object')

ใช้มันเพื่อแทนที่pandasคอลัมน์ที่มีอยู่

ตัวอย่างของวิธีที่คุณใช้ในdatซึ่งเป็น DataFrame ที่มีMultiIndexคอลัมน์:

dat = df.loc[:,['name','workshop_period','class_size']].groupby(['name','workshop_period']).describe()
print(dat.columns)
# MultiIndex(levels=[['class_size'], ['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max']],
#            codes=[[0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5, 6, 7]])

dat.columns = dat.columns.to_flat_index()
print(dat.columns)
# Index([('class_size', 'count'),  ('class_size', 'mean'),
#     ('class_size', 'std'),   ('class_size', 'min'),
#     ('class_size', '25%'),   ('class_size', '50%'),
#     ('class_size', '75%'),   ('class_size', 'max')],
#  dtype='object')

42

คำตอบของ Andy Hayden เป็นวิธีที่ง่ายที่สุดแน่นอน - หากคุณต้องการหลีกเลี่ยงการติดป้ายกำกับคอลัมน์ซ้ำคุณต้องปรับแต่งเล็กน้อย

In [34]: df
Out[34]: 
     USAF   WBAN  day  month  s_CD  s_CL  s_CNT  s_PC  tempf         year
                               sum   sum    sum   sum   amax   amin      
0  702730  26451    1      1    12     0     13     1  30.92  24.98  1993
1  702730  26451    2      1    13     0     13     0  32.00  24.98  1993
2  702730  26451    3      1     2    10     13     1  23.00   6.98  1993
3  702730  26451    4      1    12     0     13     1  10.04   3.92  1993
4  702730  26451    5      1    10     0     13     3  19.94  10.94  1993


In [35]: mi = df.columns

In [36]: mi
Out[36]: 
MultiIndex
[(USAF, ), (WBAN, ), (day, ), (month, ), (s_CD, sum), (s_CL, sum), (s_CNT, sum), (s_PC, sum), (tempf, amax), (tempf, amin), (year, )]


In [37]: mi.tolist()
Out[37]: 
[('USAF', ''),
 ('WBAN', ''),
 ('day', ''),
 ('month', ''),
 ('s_CD', 'sum'),
 ('s_CL', 'sum'),
 ('s_CNT', 'sum'),
 ('s_PC', 'sum'),
 ('tempf', 'amax'),
 ('tempf', 'amin'),
 ('year', '')]

In [38]: ind = pd.Index([e[0] + e[1] for e in mi.tolist()])

In [39]: ind
Out[39]: Index([USAF, WBAN, day, month, s_CDsum, s_CLsum, s_CNTsum, s_PCsum, tempfamax, tempfamin, year], dtype=object)

In [40]: df.columns = ind




In [46]: df
Out[46]: 
     USAF   WBAN  day  month  s_CDsum  s_CLsum  s_CNTsum  s_PCsum  tempfamax  tempfamin  \
0  702730  26451    1      1       12        0        13        1      30.92      24.98   
1  702730  26451    2      1       13        0        13        0      32.00      24.98   
2  702730  26451    3      1        2       10        13        1      23.00       6.98   
3  702730  26451    4      1       12        0        13        1      10.04       3.92   
4  702730  26451    5      1       10        0        13        3      19.94      10.94   




   year  
0  1993  
1  1993  
2  1993  
3  1993  
4  1993

2
ขอบคุณ Theodros! นี่เป็นทางออกที่ถูกต้องเพียงข้อเดียวที่รองรับทุกกรณี!
CanCeylan


14

และถ้าคุณต้องการเก็บข้อมูลการรวมใด ๆ จากระดับที่สองของ multiindex คุณสามารถลองทำสิ่งนี้:

In [1]: new_cols = [''.join(t) for t in df.columns]
Out[1]:
['USAF',
 'WBAN',
 'day',
 'month',
 's_CDsum',
 's_CLsum',
 's_CNTsum',
 's_PCsum',
 'tempfamax',
 'tempfamin',
 'year']

In [2]: df.columns = new_cols

new_colsไม่ได้กำหนดไว้
samthebrand

11

วิธีที่ไพเราะที่สุดในการทำเช่นนี้เพื่อใช้mapฟังก์ชั่น

df.columns = df.columns.map(' '.join).str.strip()

ผลผลิตprint(df.columns):

Index(['USAF', 'WBAN', 'day', 'month', 's_CD sum', 's_CL sum', 's_CNT sum',
       's_PC sum', 'tempf amax', 'tempf amin', 'year'],
      dtype='object')

อัปเดตโดยใช้ Python 3.6+ ด้วยสตริง f:

df.columns = [f'{f} {s}' if s != '' else f'{f}' 
              for f, s in df.columns]

print(df.columns)

เอาท์พุท:

Index(['USAF', 'WBAN', 'day', 'month', 's_CD sum', 's_CL sum', 's_CNT sum',
       's_PC sum', 'tempf amax', 'tempf amin', 'year'],
      dtype='object')

9

วิธีที่ง่ายและใช้งานง่ายที่สุดสำหรับฉันคือการผสมผสานชื่อคอลัมน์โดยใช้get_level_values สิ่งนี้จะป้องกันชื่อคอลัมน์ที่ซ้ำกันเมื่อคุณทำการรวมมากกว่าหนึ่งครั้งในคอลัมน์เดียวกัน:

level_one = df.columns.get_level_values(0).astype(str)
level_two = df.columns.get_level_values(1).astype(str)
df.columns = level_one + level_two

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

level_one = df.columns.get_level_values(0).astype(str)
level_two = df.columns.get_level_values(1).astype(str)
column_separator = ['_' if x != '' else '' for x in level_two]
df.columns = level_one + column_separator + level_two

ฉันรู้ว่าสิ่งนี้ทำในสิ่งเดียวกันกับคำตอบที่ดีของ Andy Hayden ด้านบน แต่ฉันคิดว่ามันเป็นวิธีที่ง่ายกว่าและจำได้ง่ายกว่า (ดังนั้นฉันไม่จำเป็นต้องอ้างอิงหัวข้อนี้) โดยเฉพาะผู้ใช้มือใหม่ .

วิธีนี้ยังสามารถขยายได้มากขึ้นในกรณีที่คุณอาจมี 3 ระดับคอลัมน์

level_one = df.columns.get_level_values(0).astype(str)
level_two = df.columns.get_level_values(1).astype(str)
level_three = df.columns.get_level_values(2).astype(str)
df.columns = level_one + level_two + level_three

6

หลังจากอ่านคำตอบทั้งหมดฉันก็พบสิ่งนี้:

def __my_flatten_cols(self, how="_".join, reset_index=True):
    how = (lambda iter: list(iter)[-1]) if how == "last" else how
    self.columns = [how(filter(None, map(str, levels))) for levels in self.columns.values] \
                    if isinstance(self.columns, pd.MultiIndex) else self.columns
    return self.reset_index() if reset_index else self
pd.DataFrame.my_flatten_cols = __my_flatten_cols

การใช้งาน:

รับกรอบข้อมูล:

df = pd.DataFrame({"grouper": ["x","x","y","y"], "val1": [0,2,4,6], 2: [1,3,5,7]}, columns=["grouper", "val1", 2])

  grouper  val1  2
0       x     0  1
1       x     2  3
2       y     4  5
3       y     6  7
  • วิธีการรวมเดี่ยว : ตัวแปรผลลัพธ์ที่มีชื่อเหมือนกับแหล่งที่มา :

    df.groupby(by="grouper").agg("min").my_flatten_cols()
    • เหมือนกับdf.groupby(by="grouper", as_index = False)หรือ . .agg(...)reset_index ()
    • ----- before -----
                 val1  2
        grouper         
      
      ------ after -----
        grouper  val1  2
      0       x     0  1
      1       y     4  5
  • ตัวแปรที่มาเดี่ยวการรวมหลายครั้ง : ตัวแปรผลลัพธ์ที่ตั้งชื่อตามสถิติ :

    df.groupby(by="grouper").agg({"val1": [min,max]}).my_flatten_cols("last")
    • a = df.groupby(..).agg(..); a.columns = a.columns.droplevel(0); a.reset_index()เช่นเดียวกับ
    • ----- before -----
                  val1    
                 min max
        grouper         
      
      ------ after -----
        grouper  min  max
      0       x    0    2
      1       y    4    6
  • หลายตัวแปรรวมตัวกันหลายอย่าง : ตัวแปรผลลัพธ์ชื่อ(varname) _ (statname) :

    df.groupby(by="grouper").agg({"val1": min, 2:[sum, "size"]}).my_flatten_cols()
    # you can combine the names in other ways too, e.g. use a different delimiter:
    #df.groupby(by="grouper").agg({"val1": min, 2:[sum, "size"]}).my_flatten_cols(" ".join)
    • ทำงานa.columns = ["_".join(filter(None, map(str, levels))) for levels in a.columns.values]ภายใต้ประทุน (เนื่องจากagg()ผลลัพธ์ในรูปแบบนี้อยู่MultiIndexในคอลัมน์)
    • หากคุณไม่มีmy_flatten_colsผู้ช่วยอาจจะง่ายกว่าในการแก้ปัญหาที่แนะนำโดย@Seigi : a.columns = ["_".join(t).rstrip("_") for t in a.columns.values]ซึ่งทำงานคล้ายกันในกรณีนี้ (แต่ล้มเหลวหากคุณมีป้ายกำกับตัวเลขในคอลัมน์)
    • หากต้องการจัดการป้ายกำกับตัวเลขบนคอลัมน์คุณสามารถใช้วิธีแก้ปัญหาที่แนะนำโดย@jxstanford และ @Nolan Conaway ( a.columns = ["_".join(tuple(map(str, t))).rstrip("_") for t in a.columns.values]) แต่ฉันไม่เข้าใจว่าเหตุใดจึงtuple()ต้องมีการโทรและฉันเชื่อว่าrstrip()จำเป็นต้องใช้หากคอลัมน์บางคอลัมน์มีตัวบ่งชี้เช่น("colname", "")( ซึ่งสามารถเกิดขึ้นได้หากคุณreset_index()ก่อนที่จะลองแก้ไข.columns)
    • ----- before -----
                 val1           2     
                 min       sum    size
        grouper              
      
      ------ after -----
        grouper  val1_min  2_sum  2_size
      0       x         0      4       2
      1       y         4     12       2
  • คุณต้องการที่จะตั้งชื่อตัวแปรที่เกิดขึ้นด้วยตนเอง: (นี่คือเลิกใช้ตั้งแต่แพนด้า 0.20.0มีทางเลือกไม่เพียงพอเป็น 0.23 )

    df.groupby(by="grouper").agg({"val1": {"sum_of_val1": "sum", "count_of_val1": "count"},
                                       2: {"sum_of_2":    "sum", "count_of_2":    "count"}}).my_flatten_cols("last")
    • คำแนะนำอื่น ๆได้แก่ : การตั้งค่าคอลัมน์ด้วยตนเอง: res.columns = ['A_sum', 'B_sum', 'count']หรือ.join()ไอเอ็นจีหลายgroupbyคำสั่ง
    • ----- before -----
                         val1                      2         
                count_of_val1 sum_of_val1 count_of_2 sum_of_2
        grouper                                              
      
      ------ after -----
        grouper  count_of_val1  sum_of_val1  count_of_2  sum_of_2
      0       x              2            2           2         4
      1       y              2           10           2        12

เคสที่จัดการโดยฟังก์ชันตัวช่วย

  • ชื่อระดับสามารถไม่ใช่สตริงเช่นดัชนีแพนด้า DataFrame ตามหมายเลขคอลัมน์เมื่อชื่อคอลัมน์เป็นจำนวนเต็มดังนั้นเราต้องแปลงด้วยmap(str, ..)
  • พวกเขาสามารถว่างเปล่าได้ดังนั้นเราต้อง filter(None, ..)
  • สำหรับคอลัมน์ระดับเดียว (เช่นอะไรก็ได้ยกเว้น MultiIndex) columns.valuesจะส่งกลับชื่อ ( strไม่ใช่ tuples)
  • ขึ้นอยู่กับว่าคุณใช้งานอย่างไรคุณ.agg()อาจต้องเก็บป้ายกำกับที่อยู่ด้านล่างสุดไว้เป็นคอลัมน์หรือต่อหลายป้ายเข้าด้วยกัน
  • (เนื่องจากฉันใหม่กับหมีแพนด้า?) บ่อยกว่านั้นฉันต้องการreset_index()ที่จะทำงานกับคอลัมน์แบบกลุ่มโดยวิธีปกติดังนั้นจึงเป็นเช่นนั้นตามค่าเริ่มต้น

คำตอบที่ดีจริงๆคุณช่วยอธิบายการทำงานของ '[" " .join (tuple (map (str, t))). rstrip (" ") สำหรับ t ใน a.columns.values]' ขอบคุณล่วงหน้า
Vineet

@Vineet ฉันอัปเดตโพสต์ของฉันเพื่อระบุว่าฉันพูดถึงตัวอย่างข้อมูลเพื่อแนะนำว่ามีผลคล้ายกับโซลูชันของฉัน หากคุณต้องการรายละเอียดเกี่ยวกับสาเหตุที่tuple()จำเป็นคุณอาจต้องการแสดงความคิดเห็นในโพสต์ของ jxstanford มิฉะนั้นมันอาจจะเป็นประโยชน์ในการตรวจสอบในตัวอย่างที่มีให้:.columns.values [('val1', 'min'), (2, 'sum'), (2, 'size')]1) for t in a.columns.valuesวนรอบคอลัมน์สำหรับคอลัมน์ที่สองt == (2, 'sum'); 2) map(str, t)ใช้str()กับ "ระดับ" แต่ละอันส่งผลให้('2', 'sum'); 3) "_".join(('2','sum'))ผลลัพธ์ใน "2_sum",
Nickolay

5

โซลูชันทั่วไปที่จัดการหลายระดับและประเภทผสม:

df.columns = ['_'.join(tuple(map(str, t))) for t in df.columns.values]

1
ในกรณีที่มีคอลัมน์ที่ไม่ใช่แบบลำดับชั้นเช่นกัน:df.columns = ['_'.join(tuple(map(str, t))).rstrip('_') for t in df.columns.values]
โนแลนโคนาเวย์

ขอบคุณ ถูกค้นหามานาน เนื่องจากดัชนีหลายระดับของฉันมีค่าจำนวนเต็ม มันได้รับการแก้ไขปัญหาของฉัน :)
AnksG

4

อาจจะช้าไปหน่อย แต่ถ้าคุณไม่กังวลเกี่ยวกับชื่อคอลัมน์ซ้ำ:

df.columns = df.columns.tolist()

สำหรับฉันนี้เปลี่ยนชื่อคอลัมน์เป็นเหมือน tuple: (year, )และ(tempf, amax)
Nickolay

3

ในกรณีที่คุณต้องการให้มีตัวคั่นในชื่อระหว่างระดับฟังก์ชั่นนี้ใช้งานได้ดี

def flattenHierarchicalCol(col,sep = '_'):
    if not type(col) is tuple:
        return col
    else:
        new_col = ''
        for leveli,level in enumerate(col):
            if not level == '':
                if not leveli == 0:
                    new_col += sep
                new_col += level
        return new_col

df.columns = df.columns.map(flattenHierarchicalCol)

1
ฉันชอบมัน. ออกจากกรณีที่คอลัมน์ที่ไม่ได้ลำดับชั้นนี้ได้ง่ายมาก:df.columns = ["_".join(filter(None, c)) for c in df.columns]
gigo

3

ต่อไปนี้ @jxstanford และ @ tvt173 ฉันได้เขียนฟังก์ชั่นด่วนที่ควรทำเคล็ดลับโดยไม่คำนึงถึงชื่อคอลัมน์สตริง / int:

def flatten_cols(df):
    df.columns = [
        '_'.join(tuple(map(str, t))).rstrip('_') 
        for t in df.columns.values
        ]
    return df

1

คุณสามารถทำได้ดังนี้ พิจารณาว่าdfเป็นดาต้าเฟรมของคุณและสมมติว่ามีดัชนีสองระดับ (เช่นในกรณีของคุณ)

df.columns = [(df.columns[i][0])+'_'+(datadf_pos4.columns[i][1]) for i in range(len(df.columns))]

1

ฉันจะแบ่งปันวิธีที่ตรงไปตรงมาที่เหมาะกับฉัน

[" ".join([str(elem) for elem in tup]) for tup in df.columns.tolist()]
#df = df.reset_index() if needed

0

หากต้องการแบน MultiIndex ภายในเชนของเมธอด DataFrame อื่นให้กำหนดฟังก์ชันดังนี้:

def flatten_index(df):
  df_copy = df.copy()
  df_copy.columns = ['_'.join(col).rstrip('_') for col in df_copy.columns.values]
  return df_copy.reset_index()

จากนั้นใช้pipeวิธีการเพื่อใช้ฟังก์ชั่นนี้ในสายโซ่ของวิธี DataFrame หลังจากgroupbyและaggก่อนหน้าวิธีอื่น ๆ ในกลุ่ม:

my_df \
  .groupby('group') \
  .agg({'value': ['count']}) \
  .pipe(flatten_index) \
  .sort_values('value_count')

0

อีกหนึ่งกิจวัตรที่เรียบง่าย

def flatten_columns(df, sep='.'):
    def _remove_empty(column_name):
        return tuple(element for element in column_name if element)
    def _join(column_name):
        return sep.join(column_name)

    new_columns = [_join(_remove_empty(column)) for column in df.columns.values]
    df.columns = new_columns
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.