簡體   English   中英

Pandas:重塑數據框

[英]Pandas: Reshaping dataframe

我有一個熊貓的相關問題。 我的數據框看起來像這樣:

  id val1 val2
0  1     0    1
1  1     1    0
2  1     0    0
3  2     1    1
4  2     1    1
5  2     1    0
6  3     0    0
7  3     0    1
8  3     1    1
9  4     1    0
10 4     0    1
11 4     0    0

我想把它變成這樣的:

             a         b        c
   id     a0   a1   b0   b1   c0   c1
    1     0    1    1    0    0    0
    2     1    1    1    1    1    0
    3     0    0    1    1    1    1
    4     1    0    0    1    0    0

我想到了一些像添加一個由 a、b 和 c 循環枚舉的 sub_id 列的方法,然后對幀進行 unstack。 有更簡單/更智能的解決方案嗎?

非常感謝!

蒂姆

如果可能的話用數字代替abc就是使用GroupBy.cumcount計數器,建立MultiIndexDataFrame.set_index和重塑DataFrame.unstack和最后排序第二水平DataFrame.swaplevel

g = df.groupby('id').cumcount()

df = df.set_index(['id', g]).unstack().sort_index(axis=1, level=1).swaplevel(0,1,axis=1)
print (df)
      0         1         2     
   val1 val2 val1 val2 val1 val2
id                              
1     0    1    1    0    0    0
2     1    1    1    1    1    0
3     0    0    0    1    1    1
4     1    0    0    1    0    0

如果想要a,b,c值可以從string.ascii_lowercase生成字典string.ascii_lowercase rename列:

import string

d = dict(enumerate(string.ascii_lowercase))
df = df.rename(columns=d)
print (df)
      a         b         c     
   val1 val2 val1 val2 val1 val2
id                              
1     0    1    1    0    0    0
2     1    1    1    1    1    0
3     0    0    0    1    1    1
4     1    0    0    1    0    0

重命名兩個級別的解決方案是首先在set_index之后按范圍創建默認列名稱:

g = df.groupby('id').cumcount()
df = df.set_index(['id', g])
df.columns = range(len(df.columns))
df = df.unstack().sort_index(axis=1, level=1).swaplevel(0,1,axis=1)
print (df)
    0     1     2   
    0  1  0  1  0  1
id                  
1   0  1  1  0  0  0
2   1  1  1  1  1  0
3   0  0  0  1  1  1
4   1  0  0  1  0  0

最后在列表理解中設置新值:

import string

d = dict(enumerate(string.ascii_lowercase))
df.columns = pd.MultiIndex.from_tuples([(d[a], f'{d[a]}{b}') for a, b in df.columns])
print (df)
    a     b     c   
   a0 a1 b0 b1 c0 c1
id                  
1   0  1  1  0  0  0
2   1  1  1  1  1  0
3   0  0  0  1  1  1
4   1  0  0  1  0  0

可能的解決方案之一:

從將每個id 的值重新格式化為一行開始:

res = df.set_index('id').groupby('id').apply(
    lambda grp: pd.Series(grp.values.flatten()))

目前的結果是:

    0  1  2  3  4  5
id                  
1   0  1  1  0  0  0
2   1  1  1  1  1  0
3   0  0  0  1  1  1
4   1  0  0  1  0  0

然后設置正確的列名:

res.columns = pd.MultiIndex.from_tuples(
    [(x, x + y) for x in list('abc') for y in list('01')])

最終結果是:

    a     b     c   
   a0 a1 b0 b1 c0 c1
id                  
1   0  1  1  0  0  0
2   1  1  1  1  1  0
3   0  0  0  1  1  1
4   1  0  0  1  0  0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM